This is an automated email from the ASF dual-hosted git repository. jky pushed a commit to branch 478-report-issue in repository https://gitbox.apache.org/repos/asf/flagon-useralejs.git
commit c702d4d9f269cabd153ca2d5ead7b00868ba329f Author: Jason Young <jason_...@protonmail.com> AuthorDate: Thu Jul 18 09:20:21 2024 -0700 Add report an issue --- build/UserALEWebExtension/background.js | 25 +++++++++++++ build/UserALEWebExtension/content.js | 12 +++++-- build/UserALEWebExtension/icons/UserALE Logo.png | Bin 0 -> 6797 bytes build/UserALEWebExtension/icons/border-48.png | Bin 225 -> 0 bytes build/UserALEWebExtension/manifest.json | 5 ++- build/UserALEWebExtension/messageTypes.d.ts | 1 + build/UserALEWebExtension/options.js | 24 +++++++++++-- build/UserALEWebExtension/optionsPage.html | 36 +++++++++++++++++-- package.json | 1 + src/UserALEWebExtension/background.ts | 24 +++++++++++++ src/UserALEWebExtension/content.ts | 14 ++++++-- src/UserALEWebExtension/icons/UserALE Logo.png | Bin 0 -> 6797 bytes src/UserALEWebExtension/icons/border-48.png | Bin 225 -> 0 bytes src/UserALEWebExtension/manifest.json | 5 ++- src/UserALEWebExtension/messageTypes.ts | 1 + src/UserALEWebExtension/options.ts | 42 ++++++++++++++++++++-- src/UserALEWebExtension/optionsPage.html | 36 +++++++++++++++++-- test/e2e/spec/01-extension.spec.ts | 43 ++++++++++++++++++++--- 18 files changed, 250 insertions(+), 19 deletions(-) diff --git a/build/UserALEWebExtension/background.js b/build/UserALEWebExtension/background.js index e17ab0d..5682410 100644 --- a/build/UserALEWebExtension/background.js +++ b/build/UserALEWebExtension/background.js @@ -71,6 +71,7 @@ const prefix = "USERALE_"; const CONFIG_CHANGE = prefix + "CONFIG_CHANGE"; const ADD_LOG = prefix + "ADD_LOG"; const HTTP_SESSION = prefix + "HTTP_SESSION"; +const ISSUE_REPORT = prefix + "ISSUE_REPORT"; var version$1 = "2.4.0"; @@ -1333,6 +1334,26 @@ function dispatchTabMessage(message) { }); }); } +/** + * Send a message to the current tab + * @param {any} message The message to send + * @return {void} + */ +function messageCurrentTab(message) { + // @ts-expect-error Typescript is not aware that firefox's broswer is overloaded + // to support chromium style MV2 callbacks + browser.tabs.query({ active: true, currentWindow: true }, function (tabs) { + console.log(tabs); + if (tabs.length > 0) { + const activeTab = tabs[0]; + browser.tabs.sendMessage(activeTab.id, message); + console.log("sent"); + } + else { + console.error("No active tab found"); + } + }); +} /** * Callback for filtering out logs with urls that do not match the regex defined in extension options. * @param {Logging.Log} log The candidate log @@ -1388,6 +1409,10 @@ browser.runtime.onMessage.addListener(function (message, sender) { case CONFIG_CHANGE: updateConfig(message.payload); break; + case ISSUE_REPORT: + console.log(ISSUE_REPORT); + messageCurrentTab(message); + break; default: console.log("got unknown message type ", message); } diff --git a/build/UserALEWebExtension/content.js b/build/UserALEWebExtension/content.js index 50055ab..77d567f 100644 --- a/build/UserALEWebExtension/content.js +++ b/build/UserALEWebExtension/content.js @@ -18,6 +18,7 @@ const prefix = "USERALE_"; const CONFIG_CHANGE = prefix + "CONFIG_CHANGE"; const ADD_LOG = prefix + "ADD_LOG"; const HTTP_SESSION = prefix + "HTTP_SESSION"; +const ISSUE_REPORT = prefix + "ISSUE_REPORT"; var version = "2.4.0"; @@ -1211,9 +1212,16 @@ browser.storage.local.get([configKey], } }); // TODO: Add types for message -browser.runtime.onMessage.addListener(function (message) { - console.log(message); +browser.runtime.onMessage.addListener(function (message, sender) { if (message.type === CONFIG_CHANGE) { options(message.payload); } + else if (message.type === ISSUE_REPORT) { + if (window.top === window) { + console.log("issue"); + packageCustomLog(message.payload, () => { + return {}; + }, true); + } + } }); diff --git a/build/UserALEWebExtension/icons/UserALE Logo.png b/build/UserALEWebExtension/icons/UserALE Logo.png new file mode 100644 index 0000000..30b4793 Binary files /dev/null and b/build/UserALEWebExtension/icons/UserALE Logo.png differ diff --git a/build/UserALEWebExtension/icons/border-48.png b/build/UserALEWebExtension/icons/border-48.png deleted file mode 100644 index 90687de..0000000 Binary files a/build/UserALEWebExtension/icons/border-48.png and /dev/null differ diff --git a/build/UserALEWebExtension/manifest.json b/build/UserALEWebExtension/manifest.json index bd26e6d..a9b341d 100644 --- a/build/UserALEWebExtension/manifest.json +++ b/build/UserALEWebExtension/manifest.json @@ -4,7 +4,7 @@ "version": "2.4.0", "description": "Injects UserALE into every page for testing & user research purposes", "icons": { - "48": "icons/border-48.png" + "48": "icons/UserALE Logo.png" }, "permissions": ["activeTab", "storage", "tabs", "<all_urls>"], "background": { @@ -19,5 +19,8 @@ ], "options_ui": { "page": "optionsPage.html" + }, + "browser_action": { + "default_popup": "optionsPage.html" } } diff --git a/build/UserALEWebExtension/messageTypes.d.ts b/build/UserALEWebExtension/messageTypes.d.ts index 00d1826..0891167 100644 --- a/build/UserALEWebExtension/messageTypes.d.ts +++ b/build/UserALEWebExtension/messageTypes.d.ts @@ -20,3 +20,4 @@ export declare const CONFIG_CHANGE: string; export declare const ADD_LOG: string; export declare const HTTP_SESSION: string; +export declare const ISSUE_REPORT: string; diff --git a/build/UserALEWebExtension/options.js b/build/UserALEWebExtension/options.js index 6b603dc..5c2f04d 100644 --- a/build/UserALEWebExtension/options.js +++ b/build/UserALEWebExtension/options.js @@ -17,6 +17,7 @@ const prefix = "USERALE_"; const CONFIG_CHANGE = prefix + "CONFIG_CHANGE"; const ADD_LOG = prefix + "ADD_LOG"; +const ISSUE_REPORT = prefix + "ISSUE_REPORT"; var version = "2.4.0"; @@ -1230,7 +1231,6 @@ function getConfig() { // to support chromium style MV2 callbacks browser.storage.local.get([configKey], (res) => { const payload = res[configKey]; - console.log(payload); const config = payload.useraleConfig; options(config); document.getElementById("url").value = config.url; @@ -1243,6 +1243,26 @@ function getConfig() { document.getElementById("filter").value = payload.pluginConfig.urlWhitelist; }); + document.getElementById("optionsForm").addEventListener("submit", setConfig); + document.getElementById("issueForm").addEventListener("submit", reportIssue); +} +function reportIssue() { + browser.runtime.sendMessage({ + type: ISSUE_REPORT, + payload: { + issueType: document.querySelector('input[name="issueType"]:checked').value, + issueDescription: document.getElementById("issueDescription").value, + type: "issue", + }, + }); } document.addEventListener("DOMContentLoaded", getConfig); -document.addEventListener("submit", setConfig); +browser.runtime.onMessage.addListener(function (message, sender) { + if (message.type === ISSUE_REPORT) { + if (window.top === window) { + packageCustomLog(message.payload, () => { + return {}; + }, true); + } + } +}); diff --git a/build/UserALEWebExtension/optionsPage.html b/build/UserALEWebExtension/optionsPage.html index 8ecd239..56a3ce0 100644 --- a/build/UserALEWebExtension/optionsPage.html +++ b/build/UserALEWebExtension/optionsPage.html @@ -23,7 +23,7 @@ <meta charset="utf-8" /> </head> <body> - <h1>Options</h1> + <h1>Logging Options</h1> <form name="optionsForm" id="optionsForm"> <label>Logging Endpoint URL:</label> <input name="url" id="url" /> @@ -50,7 +50,39 @@ <br /> <div align="right"> - <button type="submit" id="submit">Save</button> + <button type="submit" id="submitOptions">Save Changes</button> + </div> + </form> + <h1>Report an Issue</h1> + <form name="issueForm" id="issueForm"> + <label>Issue Type</label><br /> + <label> + <input + type="radio" + id="bug" + name="issueType" + value="Bug" + checked="checked" + /> + Bug </label + ><br /> + + <label> + <input type="radio" id="feat" name="issueType" value="Feature" /> + Feature Request </label + ><br /> + <br /> + <textarea + id="issueDescription" + name="issueDescription" + rows="5" + cols="50" + > +A detailed description of the issue.</textarea + > + <br /> + <div align="right"> + <button type="submit" id="submitIssue">Submit Report</button> </div> </form> </body> diff --git a/package.json b/package.json index 923e35a..df03057 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "test": "npm run test:unit && npm run test:e2e", "test:unit": "jest -c ./test/unit/jest.config.ts", "test:e2e": "playwright test -c ./test/e2e/playwright.config.ts", + "pretest:e2e": "rm -rf ./test/e2e/chromeData/*", "posttest:e2e": "rm -rf ./test/e2e/chromeData/*", "example:run": "node example/server.js", "example:watch": "nodemon -w ./example example/server.js", diff --git a/src/UserALEWebExtension/background.ts b/src/UserALEWebExtension/background.ts index 5c27fe1..271d360 100644 --- a/src/UserALEWebExtension/background.ts +++ b/src/UserALEWebExtension/background.ts @@ -98,6 +98,25 @@ function dispatchTabMessage(message: any) { }); }); } +/** + * Send a message to the current tab + * @param {any} message The message to send + * @return {void} + */ +function messageCurrentTab(message: any) { + // @ts-expect-error Typescript is not aware that firefox's broswer is overloaded + // to support chromium style MV2 callbacks + browser.tabs.query({ active: true, currentWindow: true }, function (tabs) { + console.log(tabs); + if (tabs.length > 0) { + const activeTab = tabs[0]; + browser.tabs.sendMessage(activeTab.id, message); + console.log("sent"); + } else { + console.error("No active tab found"); + } + }); +} /** * Callback for filtering out logs with urls that do not match the regex defined in extension options. @@ -159,6 +178,11 @@ browser.runtime.onMessage.addListener(function (message, sender) { updateConfig(message.payload); break; + case MessageTypes.ISSUE_REPORT: + console.log(MessageTypes.ISSUE_REPORT); + messageCurrentTab(message); + break; + default: console.log("got unknown message type ", message); } diff --git a/src/UserALEWebExtension/content.ts b/src/UserALEWebExtension/content.ts index 225d821..a52af8f 100644 --- a/src/UserALEWebExtension/content.ts +++ b/src/UserALEWebExtension/content.ts @@ -40,9 +40,19 @@ browser.storage.local.get( ); // TODO: Add types for message -browser.runtime.onMessage.addListener(function (message) { - console.log(message); +browser.runtime.onMessage.addListener(function (message, sender) { if (message.type === MessageTypes.CONFIG_CHANGE) { userale.options(message.payload); + } else if (message.type === MessageTypes.ISSUE_REPORT) { + if (window.top === window) { + console.log("issue"); + userale.packageCustomLog( + message.payload, + () => { + return {}; + }, + true, + ); + } } }); diff --git a/src/UserALEWebExtension/icons/UserALE Logo.png b/src/UserALEWebExtension/icons/UserALE Logo.png new file mode 100644 index 0000000..30b4793 Binary files /dev/null and b/src/UserALEWebExtension/icons/UserALE Logo.png differ diff --git a/src/UserALEWebExtension/icons/border-48.png b/src/UserALEWebExtension/icons/border-48.png deleted file mode 100644 index 90687de..0000000 Binary files a/src/UserALEWebExtension/icons/border-48.png and /dev/null differ diff --git a/src/UserALEWebExtension/manifest.json b/src/UserALEWebExtension/manifest.json index bd26e6d..a9b341d 100644 --- a/src/UserALEWebExtension/manifest.json +++ b/src/UserALEWebExtension/manifest.json @@ -4,7 +4,7 @@ "version": "2.4.0", "description": "Injects UserALE into every page for testing & user research purposes", "icons": { - "48": "icons/border-48.png" + "48": "icons/UserALE Logo.png" }, "permissions": ["activeTab", "storage", "tabs", "<all_urls>"], "background": { @@ -19,5 +19,8 @@ ], "options_ui": { "page": "optionsPage.html" + }, + "browser_action": { + "default_popup": "optionsPage.html" } } diff --git a/src/UserALEWebExtension/messageTypes.ts b/src/UserALEWebExtension/messageTypes.ts index 1328c8a..94846fb 100644 --- a/src/UserALEWebExtension/messageTypes.ts +++ b/src/UserALEWebExtension/messageTypes.ts @@ -20,3 +20,4 @@ const prefix = "USERALE_"; export const CONFIG_CHANGE = prefix + "CONFIG_CHANGE"; export const ADD_LOG = prefix + "ADD_LOG"; export const HTTP_SESSION = prefix + "HTTP_SESSION"; +export const ISSUE_REPORT = prefix + "ISSUE_REPORT"; diff --git a/src/UserALEWebExtension/options.ts b/src/UserALEWebExtension/options.ts index ba89b5f..4e89141 100644 --- a/src/UserALEWebExtension/options.ts +++ b/src/UserALEWebExtension/options.ts @@ -62,7 +62,6 @@ function getConfig() { // to support chromium style MV2 callbacks browser.storage.local.get([configKey], (res) => { const payload = res[configKey]; - console.log(payload); const config = payload.useraleConfig; userale.options(config); @@ -76,7 +75,46 @@ function getConfig() { (document.getElementById("filter") as HTMLInputElement).value = payload.pluginConfig.urlWhitelist; }); + + (document.getElementById("optionsForm") as HTMLFormElement).addEventListener( + "submit", + setConfig, + ); + (document.getElementById("issueForm") as HTMLFormElement).addEventListener( + "submit", + reportIssue, + ); +} + +function reportIssue() { + browser.runtime.sendMessage({ + type: MessageTypes.ISSUE_REPORT, + payload: { + issueType: ( + document.querySelector( + 'input[name="issueType"]:checked', + ) as HTMLButtonElement + ).value, + issueDescription: ( + document.getElementById("issueDescription") as HTMLTextAreaElement + ).value, + type: "issue", + }, + }); } document.addEventListener("DOMContentLoaded", getConfig); -document.addEventListener("submit", setConfig); + +browser.runtime.onMessage.addListener(function (message, sender) { + if (message.type === MessageTypes.ISSUE_REPORT) { + if (window.top === window) { + userale.packageCustomLog( + message.payload, + () => { + return {}; + }, + true, + ); + } + } +}); diff --git a/src/UserALEWebExtension/optionsPage.html b/src/UserALEWebExtension/optionsPage.html index 8ecd239..56a3ce0 100644 --- a/src/UserALEWebExtension/optionsPage.html +++ b/src/UserALEWebExtension/optionsPage.html @@ -23,7 +23,7 @@ <meta charset="utf-8" /> </head> <body> - <h1>Options</h1> + <h1>Logging Options</h1> <form name="optionsForm" id="optionsForm"> <label>Logging Endpoint URL:</label> <input name="url" id="url" /> @@ -50,7 +50,39 @@ <br /> <div align="right"> - <button type="submit" id="submit">Save</button> + <button type="submit" id="submitOptions">Save Changes</button> + </div> + </form> + <h1>Report an Issue</h1> + <form name="issueForm" id="issueForm"> + <label>Issue Type</label><br /> + <label> + <input + type="radio" + id="bug" + name="issueType" + value="Bug" + checked="checked" + /> + Bug </label + ><br /> + + <label> + <input type="radio" id="feat" name="issueType" value="Feature" /> + Feature Request </label + ><br /> + <br /> + <textarea + id="issueDescription" + name="issueDescription" + rows="5" + cols="50" + > +A detailed description of the issue.</textarea + > + <br /> + <div align="right"> + <button type="submit" id="submitIssue">Submit Report</button> </div> </form> </body> diff --git a/test/e2e/spec/01-extension.spec.ts b/test/e2e/spec/01-extension.spec.ts index 8db72bc..9341e41 100644 --- a/test/e2e/spec/01-extension.spec.ts +++ b/test/e2e/spec/01-extension.spec.ts @@ -32,6 +32,7 @@ test.describe("Userale extension", () => { await requestPromise; throw new Error("request made"); } catch (err) { + console.log(err); expect(err).toBeInstanceOf(errors.TimeoutError); } }); @@ -44,7 +45,7 @@ test.describe("Userale extension", () => { // Sleep so options.js can update the html with values from local storage. await new Promise((r) => setTimeout(r, 1000)); await page.fill("#filter", ".*"); - await page.click("#submit"); + await page.click("#submitOptions"); await page.goto("./"); for (let i = 0; i < 5; i++) { await page.getByText("Click Me!", { exact: true }).click(); @@ -61,10 +62,9 @@ test.describe("Userale extension", () => { return Boolean(postData && postData.includes("testUser")); }); await page.goto(`chrome-extension://${extensionId}/optionsPage.html`); - // Sleep so options.js can update the html with values from local storage. - await new Promise((r) => setTimeout(r, 1000)); + await page.waitForLoadState("load"); await page.fill("#user", id); - await page.click("#submit"); + await page.click("#submitOptions"); await page.goto("./"); for (let i = 0; i < 5; i++) { await page.getByText("Click Me!", { exact: true }).click(); @@ -74,6 +74,39 @@ test.describe("Userale extension", () => { const body = await request.postDataJSON(); const log = body.find((log: Logging.JSONObject) => log.userId === id); - expect(log).not.toBeNull(); + expect(log).toBeTruthy; + }); + + test("can submit an issue report", async ({ + context, + sender, + page, + extensionId, + }) => { + let description = "test description 123"; + const requestPromise = sender.waitForRequest((request) => { + const postData = request.postData(); + return Boolean(postData && postData.includes(description)); + }); + await page.goto(`chrome-extension://${extensionId}/optionsPage.html`); + await page.waitForLoadState("load"); + await page.fill("#issueDescription", description); + await page.click("#submitIssue"); + + const request = await requestPromise; + const body = await request.postDataJSON(); + const log: Logging.JSONObject = body.find( + (log: Logging.JSONObject) => log.type === "issue", + ); + + const expectedLog: Logging.JSONObject = { + issueDescription: description, + issueType: "Bug", + type: "issue", + }; + for (const key of Object.keys(expectedLog)) { + expect(log).toHaveProperty(key); + expect(log[key]).toEqual(expectedLog[key]); + } }); });