Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deps: remove deprecated content-scope-utils #384

Merged
merged 2 commits into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4,018 changes: 1,959 additions & 2,059 deletions dist/autofill-debug.js

Large diffs are not rendered by default.

1,778 changes: 839 additions & 939 deletions dist/autofill.js

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion integration-test/helpers/mocks.android.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,6 @@ export function createAndroidMocks () {
},
storeFormData (request) {
/** @type {MockCall} */
// @ts-expect-error
const call = ['storeFormData', request, mocks.getAutofillData]
window.__playwright_autofill.mocks.calls.push(JSON.parse(JSON.stringify(call)))
}
Expand Down
2 changes: 0 additions & 2 deletions integration-test/helpers/pages.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
await expect(getCallToAction()).toBeHidden()
}
async getEmailProtection () {
(await getCallToAction()).click({timeout: 500})

Check failure on line 34 in integration-test/helpers/pages.js

View workflow job for this annotation

GitHub Actions / test

[extension] › incontext-signup.extension.spec.js:14:5 › chrome extension › should allow user to sign up for Email Protection

1) [extension] › incontext-signup.extension.spec.js:14:5 › chrome extension › should allow user to sign up for Email Protection TimeoutError: locator.click: Timeout 500ms exceeded. =========================== logs =========================== waiting for locator('text=Protect My Email') locator resolved to <a target="_blank" class="primary js-get-email-sign…>↵ Protect My Email↵ </a> attempting click action waiting for element to be visible, enabled and stable ============================================================ at ../helpers/pages.js:34 32 | } 33 | async getEmailProtection () { > 34 | (await getCallToAction()).click({timeout: 500}) | ^ 35 | } 36 | async dismissTooltipWith (text) { 37 | const dismissTooltipButton = await page.locator(`text=${text}`) at IncontextSignupPage.getEmailProtection (/home/runner/work/duckduckgo-autofill/duckduckgo-autofill/integration-test/helpers/pages.js:34:39) at /home/runner/work/duckduckgo-autofill/duckduckgo-autofill/integration-test/tests/incontext-signup.extension.spec.js:32:9
}
async dismissTooltipWith (text) {
const dismissTooltipButton = await page.locator(`text=${text}`)
Expand All @@ -39,7 +39,7 @@
}
async closeTooltip () {
const dismissTooltipButton = await page.locator(`[aria-label=Close]`)
await dismissTooltipButton.click({timeout: 500})

Check failure on line 42 in integration-test/helpers/pages.js

View workflow job for this annotation

GitHub Actions / test

[extension] › incontext-signup.extension.spec.js:64:5 › chrome extension › should allow tooltip to be closed

2) [extension] › incontext-signup.extension.spec.js:64:5 › chrome extension › should allow tooltip to be closed TimeoutError: locator.click: Timeout 500ms exceeded. =========================== logs =========================== waiting for locator('[aria-label=Close]') locator resolved to <button aria-label="Close" class="close-tooltip js-close…></button> attempting click action waiting for element to be visible, enabled and stable ============================================================ at ../helpers/pages.js:42 40 | async closeTooltip () { 41 | const dismissTooltipButton = await page.locator(`[aria-label=Close]`) > 42 | await dismissTooltipButton.click({timeout: 500}) | ^ 43 | } 44 | async clickDirectlyOnDax () { 45 | const input = page.locator(selectors.identity) at IncontextSignupPage.closeTooltip (/home/runner/work/duckduckgo-autofill/duckduckgo-autofill/integration-test/helpers/pages.js:42:40) at /home/runner/work/duckduckgo-autofill/duckduckgo-autofill/integration-test/tests/incontext-signup.extension.spec.js:75:9
}
async clickDirectlyOnDax () {
const input = page.locator(selectors.identity)
Expand Down Expand Up @@ -170,7 +170,7 @@
const [, generatedPassword] = passwordButtonText.split('\n')

if (!generatedPassword.trim()) {
throw new Error('unreachable - password must not be empty')

Check failure on line 173 in integration-test/helpers/pages.js

View workflow job for this annotation

GitHub Actions / test

[macos] › email-autofill.macos.spec.js:156:9 › macos › auto filling a signup form › with an identity only - filling firstName + generated password

3) [macos] › email-autofill.macos.spec.js:156:9 › macos › auto filling a signup form › with an identity only - filling firstName + generated password Error: unreachable - password must not be empty at ../helpers/pages.js:173 171 | 172 | if (!generatedPassword.trim()) { > 173 | throw new Error('unreachable - password must not be empty') | ^ 174 | } 175 | 176 | await passwordBtn.click({ force: true }) at SignupPage.selectGeneratedPassword (/home/runner/work/duckduckgo-autofill/duckduckgo-autofill/integration-test/helpers/pages.js:173:23) at /home/runner/work/duckduckgo-autofill/duckduckgo-autofill/integration-test/tests/email-autofill.macos.spec.js:169:13

Check failure on line 173 in integration-test/helpers/pages.js

View workflow job for this annotation

GitHub Actions / test

[macos] › email-autofill.macos.spec.js:196:9 › macos › auto filling a signup form › with an identity + Email Protection

4) [macos] › email-autofill.macos.spec.js:196:9 › macos › auto filling a signup form › with an identity + Email Protection, autofill using duck address in identity Error: unreachable - password must not be empty at ../helpers/pages.js:173 171 | 172 | if (!generatedPassword.trim()) { > 173 | throw new Error('unreachable - password must not be empty') | ^ 174 | } 175 | 176 | await passwordBtn.click({ force: true }) at SignupPage.selectGeneratedPassword (/home/runner/work/duckduckgo-autofill/duckduckgo-autofill/integration-test/helpers/pages.js:173:23) at /home/runner/work/duckduckgo-autofill/duckduckgo-autofill/integration-test/tests/email-autofill.macos.spec.js:210:13
}

await passwordBtn.click({ force: true })
Expand Down Expand Up @@ -283,7 +283,6 @@
const calls = await mockedCalls(page, { names: ['storeFormData'] })
expect(calls.length).toBeGreaterThanOrEqual(1)
const [, sent] = calls[0]
// @ts-expect-error
expect(sent.Data.credentials).toEqual(credentials)
}
/**
Expand All @@ -306,7 +305,7 @@
expect(await emailStyleAttr()).toBeFalsy()
}
async assertPasswordHasNoIcon () {
expect(await passwordStyleAttr()).toBeFalsy()

Check failure on line 308 in integration-test/helpers/pages.js

View workflow job for this annotation

GitHub Actions / test

[macos] › mutating-form.macos.spec.js:19:5 › Mutating form page › works fine on macOS

5) [macos] › mutating-form.macos.spec.js:19:5 › Mutating form page › works fine on macOS ───────── Error: expect(received).toBeFalsy() Received: "background-size: auto 100% !important; background-position: right !important; background-repeat: no-repeat !important; background-origin: content-box !important; background-image: url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMjRweCIgaGVpZ2h0PSIyNHB4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8dGl0bGU+ZGRnLXBhc3N3b3JkLWljb24tYmFzZTwvdGl0bGU+CiAgICA8ZyBpZD0iZGRnLXBhc3N3b3JkLWljb24tYmFzZSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9IlVuaW9uIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0LjAwMDAwMCwgNC4wMDAwMDApIiBmaWxsPSIjMDAwMDAwIj4KICAgICAgICAgICAgPHBhdGggZD0iTTExLjMzMzMsMi42NjY2NyBDMTAuMjI4OCwyLjY2NjY3IDkuMzMzMzMsMy41NjIxIDkuMzMzMzMsNC42NjY2NyBDOS4zMzMzMyw1Ljc3MTI0IDEwLjIyODgsNi42NjY2NyAxMS4zMzMzLDYuNjY2NjcgQzEyLjQzNzksNi42NjY2NyAxMy4zMzMzLDUuNzcxMjQgMTMuMzMzMyw0LjY2NjY3IEMxMy4zMzMzLDMuNTYyMSAxMi40Mzc5LDIuNjY2NjcgMTEuMzMzMywyLjY2NjY3IFogTTEwLjY2NjcsNC42NjY2NyBDMTAuNjY2Nyw0LjI5ODQ4IDEwLjk2NTEsNCAxMS4zMzMzLDQgQzExLjcwMTUsNCAxMiw0LjI5ODQ4IDEyLDQuNjY2NjcgQzEyLDUuMDM0ODYgMTEuNzAxNSw1LjMzMzMzIDExLjMzMzMsNS4zMzMzMyBDMTAuOTY1MSw1LjMzMzMzIDEwLjY2NjcsNS4wMzQ4NiAxMC42NjY3LDQuNjY2NjcgWiIgaWQ9IlNoYXBlIj48L3BhdGg+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0xMC42NjY3LDAgQzcuNzIxMTUsMCA1LjMzMzMzLDIuMzg3ODEgNS4zMzMzMyw1LjMzMzMzIEM1LjMzMzMzLDUuNzYxMTkgNS4zODM4NSw2LjE3Nzk4IDUuNDc5NDUsNi41Nzc3NSBMMC4xOTUyNjIsMTEuODYxOSBDMC4wNzAyMzc5LDExLjk4NyAwLDEyLjE1NjUgMCwxMi4zMzMzIEwwLDE1LjMzMzMgQzAsMTUuNzAxNSAwLjI5ODQ3NywxNiAwLjY2NjY2NywxNiBMMy4zMzMzMywxNiBDNC4wNjk3MSwxNiA0LjY2NjY3LDE1LjQwMyA0LjY2NjY3LDE0LjY2NjcgTDQuNjY2NjcsMTQgTDUuMzMzMzMsMTQgQzYuMDY5NzEsMTQgNi42NjY2NywxMy40MDMgNi42NjY2NywxMi42NjY3IEw2LjY2NjY3LDExLjMzMzMgTDgsMTEuMzMzMyBDOC4xNzY4MSwxMS4zMzMzIDguMzQ2MzgsMTEuMjYzMSA4LjQ3MTQxLDExLjEzODEgTDkuMTU5MDYsMTAuNDUwNCBDOS42Mzc3MiwxMC41OTEyIDEwLjE0MzksMTAuNjY2NyAxMC42NjY3LDEwLjY2NjcgQzEzLjYxMjIsMTAuNjY2NyAxNiw4LjI3ODg1IDE2LDUuMzMzMzMgQzE2LDIuMzg3ODEgMTMuNjEyMiwwIDEwLjY2NjcsMCBaIE02LjY2NjY3LDUuMzMzMzMgQzYuNjY2NjcsMy4xMjQxOSA4LjQ1NzUzLDEuMzMzMzMgMTAuNjY2NywxLjMzMzMzIEMxMi44NzU4LDEuMzMzMzMgMTQuNjY2NywzLjEyNDE5IDE0LjY2NjcsNS4zMzMzMyBDMTQuNjY2Nyw3LjU0MjQ3IDEyLjg3NTgsOS4zMzMzMyAxMC42NjY3LDkuMzMzMzMgQzEwLjE1NTgsOS4zMzMzMyA5LjY2ODg2LDkuMjM3OSA5LjIyMTUyLDkuMDY0NSBDOC45NzUyOCw4Ljk2OTA1IDguNjk1OTEsOS4wMjc5NSA4LjUwOTE2LDkuMjE0NjkgTDcuNzIzODYsMTAgTDYsMTAgQzUuNjMxODEsMTAgNS4zMzMzMywxMC4yOTg1IDUuMzMzMzMsMTAuNjY2NyBMNS4zMzMzMywxMi42NjY3IEw0LDEyLjY2NjcgQzMuNjMxODEsMTIuNjY2NyAzLjMzMzMzLDEyLjk2NTEgMy4zMzMzMywxMy4zMzMzIEwzLjMzMzMzLDE0LjY2NjcgTDEuMzMzMzMsMTQuNjY2NyBMMS4zMzMzMywxMi42MDk1IEw2LjY5Nzg3LDcuMjQ0OTQgQzYuODc1MDIsNy4wNjc3OSA2LjkzNzksNi44MDYyOSA2Ljg2MDY1LDYuNTY3OTggQzYuNzM0ODksNi4xNzk5NyA2LjY2NjY3LDUuNzY1MjcgNi42NjY2Nyw1LjMzMzMzIFoiIGlkPSJTaGFwZSI+PC9wYXRoPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+\") !important; transition: background !important;" at ../helpers/pages.js:308 306 | } 307 | async assertPasswordHasNoIcon () { > 308 | expect(await passwordStyleAttr()).toBeFalsy() | ^ 309 | } 310 | } 311 | at SignupPage.assertPasswordHasNoIcon (/home/runner/work/duckduckgo-autofill/duckduckgo-autofill/integration-test/helpers/pages.js:308:47) at /home/runner/work/duckduckgo-autofill/duckduckgo-autofill/integration-test/tests/mutating-form.macos.spec.js:34:9
}
}

Expand Down Expand Up @@ -481,7 +480,6 @@
*/
async assertParentOpened () {
const credsCalls = await mockedCalls(page, { names: ['getSelectedCredentials'] })
// @ts-expect-error
const hasSucceeded = credsCalls.some((call) => call[2]?.some(({type}) => type === 'ok'))
expect(hasSucceeded).toBe(true)
}
Expand Down
12 changes: 0 additions & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
"@babel/eslint-parser": "^7.18.2",
"@babel/preset-env": "^7.16.11",
"@duckduckgo/content-scope-scripts": "github:duckduckgo/content-scope-scripts#1.3.0",
"@duckduckgo/content-scope-utils": "github:duckduckgo/content-scope-utils#1.0.1",
"@playwright/test": "^1.32.0",
"@types/jest": "^27.4.1",
"@types/node": "^16.11.36",
Expand Down
154 changes: 154 additions & 0 deletions packages/messaging/messaging.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/**
* @module Messaging
*
* @description
*
* An abstraction for communications between JavaScript and host platforms.
*
* 1) First you construct your platform-specific configuration (eg: {@link WebkitMessagingConfig})
* 2) Then use that to get an instance of the Messaging utility which allows
* you to send and receive data in a unified way
* 3) Each platform implements {@link MessagingTransport} along with its own Configuration
* - For example, to learn what configuration is required for Webkit, see: {@link "Webkit Messaging".WebkitMessagingConfig}
* - Or, to learn about how messages are sent and received in Webkit, see {@link "Webkit Messaging".WebkitMessagingTransport}
*
* @example Webkit Messaging
*
* ```js
* import { Messaging, WebkitMessagingConfig } from "@duckduckgo/content-scope-scripts/lib/messaging.js"
*
* // This config would be injected into the UserScript
* const injectedConfig = {
* hasModernWebkitAPI: true,
* webkitMessageHandlerNames: ["foo", "bar", "baz"],
* secret: "dax",
* };
*
* // Then use that config to construct platform-specific configuration
* const config = new WebkitMessagingConfig(injectedConfig);
*
* // finally, get an instance of Messaging and start sending messages in a unified way 🚀
* const messaging = new Messaging(config);
* messaging.notify("hello world!", {foo: "bar"})
*
* ```
*
* @example Windows Messaging
*
* ```js
* import { Messaging, WindowsMessagingConfig } from "@duckduckgo/content-scope-scripts/lib/messaging.js"
*
* // Messaging on Windows is namespaced, so you can create multiple messaging instances
* const autofillConfig = new WindowsMessagingConfig({ featureName: "Autofill" });
* const debugConfig = new WindowsMessagingConfig({ featureName: "Debugging" });
*
* const autofillMessaging = new Messaging(autofillConfig);
* const debugMessaging = new Messaging(debugConfig);
*
* // Now send messages to both features as needed 🚀
* autofillMessaging.notify("storeFormData", { "username": "dax" })
* debugMessaging.notify("pageLoad", { time: window.performance.now() })
* ```
*/
import { WebkitMessagingConfig, WebkitMessagingTransport } from './webkit.js'

/**
* @implements {MessagingTransport}
*/
export class Messaging {
/**
* @param {WebkitMessagingConfig} config
*/
constructor (config) {
this.transport = getTransport(config)
}
/**
* Send a 'fire-and-forget' message.
* @throws {Error}
* {@link MissingHandler}
*
* @example
*
* ```
* const messaging = new Messaging(config)
* messaging.notify("foo", {bar: "baz"})
* ```
* @param {string} name
* @param {Record<string, any>} [data]
*/
notify (name, data = {}) {
this.transport.notify(name, data)
}
/**
* Send a request, and wait for a response
* @throws {Error}
* {@link MissingHandler}
*
* @example
* ```
* const messaging = new Messaging(config)
* const response = await messaging.request("foo", {bar: "baz"})
* ```
*
* @param {string} name
* @param {Record<string, any>} [data]
* @return {Promise<any>}
*/
request (name, data = {}) {
return this.transport.request(name, data)
}
}

/**
* @interface
*/
export class MessagingTransport {
/**
* @param {string} name
* @param {Record<string, any>} [data]
* @returns {void}
*/
// @ts-ignore - ignoring a no-unused ts error, this is only an interface.
notify (name, data = {}) {
throw new Error("must implement 'notify'")
}
/**
* @param {string} name
* @param {Record<string, any>} [data]
* @return {Promise<any>}
*/
// @ts-ignore - ignoring a no-unused ts error, this is only an interface.
request (name, data = {}) {
throw new Error('must implement')
}
}

/**
* @param {WebkitMessagingConfig} config
* @returns {MessagingTransport}
*/
function getTransport (config) {
if (config instanceof WebkitMessagingConfig) {
return new WebkitMessagingTransport(config)
}
throw new Error('unreachable')
}

/**
* Thrown when a handler cannot be found
*/
export class MissingHandler extends Error {
/**
* @param {string} message
* @param {string} handlerName
*/
constructor (message, handlerName) {
super(message)
this.handlerName = handlerName
}
}

/**
* Some re-exports for convenience
*/
export { WebkitMessagingConfig }
Loading
Loading