From 191c1f849197003f933791d1ecc52519c4d11a9e Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Mon, 13 Jan 2025 16:45:53 +0530 Subject: [PATCH 1/7] add e2e tests --- src/pages/popup/components/NotMonetized.tsx | 7 +- tests/e2e/special.spec.ts | 140 ++++++++++++++++++++ 2 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 tests/e2e/special.spec.ts diff --git a/src/pages/popup/components/NotMonetized.tsx b/src/pages/popup/components/NotMonetized.tsx index a51b0ca4..60a6a9c4 100644 --- a/src/pages/popup/components/NotMonetized.tsx +++ b/src/pages/popup/components/NotMonetized.tsx @@ -7,7 +7,12 @@ export const NotMonetized = ({ text }: { text: string }) => {
-

{text}

+

+ {text} +

); }; diff --git a/tests/e2e/special.spec.ts b/tests/e2e/special.spec.ts new file mode 100644 index 00000000..2f274e53 --- /dev/null +++ b/tests/e2e/special.spec.ts @@ -0,0 +1,140 @@ +import { spy } from 'tinyspy'; +import { test, expect } from './fixtures/connected'; + +test('iframe add/remove does not de-monetize main page', async ({ + page, + background, + popup, +}) => { + const walletAddressUrl = process.env.TEST_WALLET_ADDRESS_URL; + const playgroundUrl = 'https://webmonetization.org/play/'; + + const monetizationCallback = await test.step('prepare', async () => { + await expect(popup.getByTestId('not-monetized-message')).toBeVisible(); + + await page.goto(playgroundUrl); + + const monetizationCallback = spy<[Event], void>(); + await page.exposeFunction('monetizationCallback', monetizationCallback); + await page.evaluate(() => { + window.addEventListener('monetization', monetizationCallback); + }); + + await page + .getByLabel('Wallet address/Payment pointer') + .fill(walletAddressUrl); + await page.getByRole('button', { name: 'Add monetization link' }).click(); + + await page.$eval( + 'link[rel="monetization"]', + (el) => new Promise((res) => el.addEventListener('load', res)), + ); + + await page.waitForTimeout(2000); + await expect(monetizationCallback).toHaveBeenCalledTimes(1); + await expect(monetizationCallback).toHaveBeenLastCalledWithMatching({ + paymentPointer: walletAddressUrl, + }); + + await expect(popup.getByTestId('home-page')).toBeVisible(); + + return monetizationCallback; + }); + + await test.step('add iframe', async () => { + await page.evaluate(() => { + return new Promise((resolve) => { + const iframe = document.createElement('iframe'); + iframe.id = 'cross-origin-iframe'; + iframe.src = 'https://example.com'; + document.body.prepend(iframe); + iframe.addEventListener('load', resolve); + }); + }); + + await expect(page.locator('#cross-origin-iframe')).toBeVisible(); + await expect(popup.getByTestId('home-page')).toBeVisible(); + }); + + await test.step('remove iframe', async () => { + await page.evaluate(() => { + const iframe = document.getElementById('cross-origin-iframe'); + iframe?.remove(); + }); + await expect(page.locator('#cross-origin-iframe')).not.toBeAttached(); + + await expect(popup.getByTestId('not-monetized-message')).not.toBeVisible(); + await expect(popup.getByTestId('home-page')).toBeVisible(); + }); +}); + +test('iframe navigate does not de-monetize main page', async ({ + page, + background, + popup, +}) => { + const walletAddressUrl = process.env.TEST_WALLET_ADDRESS_URL; + const playgroundUrl = 'https://webmonetization.org/play/'; + + const monetizationCallback = await test.step('prepare', async () => { + await expect(popup.getByTestId('not-monetized-message')).toBeVisible(); + + await page.goto(playgroundUrl); + + const monetizationCallback = spy<[Event], void>(); + await page.exposeFunction('monetizationCallback', monetizationCallback); + await page.evaluate(() => { + window.addEventListener('monetization', monetizationCallback); + }); + + await page + .getByLabel('Wallet address/Payment pointer') + .fill(walletAddressUrl); + await page.getByRole('button', { name: 'Add monetization link' }).click(); + + await page.$eval( + 'link[rel="monetization"]', + (el) => new Promise((res) => el.addEventListener('load', res)), + ); + + await page.waitForTimeout(2000); + await expect(monetizationCallback).toHaveBeenCalledTimes(1); + await expect(monetizationCallback).toHaveBeenLastCalledWithMatching({ + paymentPointer: walletAddressUrl, + }); + + await expect(popup.getByTestId('home-page')).toBeVisible(); + + return monetizationCallback; + }); + + await test.step('add iframe', async () => { + await page.evaluate(() => { + return new Promise((resolve) => { + const iframe = document.createElement('iframe'); + iframe.id = 'cross-origin-iframe'; + iframe.src = 'https://example.com'; + document.body.prepend(iframe); + iframe.addEventListener('load', resolve, { once: true }); + }); + }); + }); + + await test.step('navigate iframe', async () => { + await page.evaluate(() => { + return new Promise((resolve, reject) => { + const iframe = document.getElementById('cross-origin-iframe'); + if (!iframe) { + reject(new Error('iframe not found')); + return; + } + iframe.addEventListener('load', resolve, { once: true }); + iframe.addEventListener('error', resolve, { once: true }); + iframe.setAttribute('src', 'https://example.com/test'); + }); + }); + + await expect(popup.getByTestId('not-monetized-message')).not.toBeVisible(); + await expect(popup.getByTestId('home-page')).toBeVisible(); + }); +}); From 63bbca4eb1930c71c455ee2c759d4b8e2026af01 Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Mon, 13 Jan 2025 17:09:38 +0530 Subject: [PATCH 2/7] mark test as failing --- tests/e2e/special.spec.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/e2e/special.spec.ts b/tests/e2e/special.spec.ts index 2f274e53..e1d54020 100644 --- a/tests/e2e/special.spec.ts +++ b/tests/e2e/special.spec.ts @@ -120,6 +120,10 @@ test('iframe navigate does not de-monetize main page', async ({ }); }); + test.fail( + true, + 'https://github.com/interledger/web-monetization-extension/issues/819', + ); await test.step('navigate iframe', async () => { await page.evaluate(() => { return new Promise((resolve, reject) => { From d4f396a632b857bb1ebffa71d0be64324b71d7b7 Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Mon, 13 Jan 2025 17:22:43 +0530 Subject: [PATCH 3/7] enable noUnusedVariables linter rule --- biome.jsonc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/biome.jsonc b/biome.jsonc index 3393a1f2..1c7adf7f 100644 --- a/biome.jsonc +++ b/biome.jsonc @@ -28,6 +28,9 @@ "noExplicitAny": "off", // TODO: turn on, too many cases "noConsole": "warn" }, + "correctness": { + "noUnusedVariables": "warn" + }, "a11y": { "noSvgWithoutTitle": "off" } From 72983934032cb90c0e7eb8e78a7fb40545d04700 Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Mon, 13 Jan 2025 17:24:22 +0530 Subject: [PATCH 4/7] remove unused vars --- tests/e2e/special.spec.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/e2e/special.spec.ts b/tests/e2e/special.spec.ts index e1d54020..5ff3f48e 100644 --- a/tests/e2e/special.spec.ts +++ b/tests/e2e/special.spec.ts @@ -3,13 +3,12 @@ import { test, expect } from './fixtures/connected'; test('iframe add/remove does not de-monetize main page', async ({ page, - background, popup, }) => { const walletAddressUrl = process.env.TEST_WALLET_ADDRESS_URL; const playgroundUrl = 'https://webmonetization.org/play/'; - const monetizationCallback = await test.step('prepare', async () => { + await test.step('prepare', async () => { await expect(popup.getByTestId('not-monetized-message')).toBeVisible(); await page.goto(playgroundUrl); @@ -70,13 +69,12 @@ test('iframe add/remove does not de-monetize main page', async ({ test('iframe navigate does not de-monetize main page', async ({ page, - background, popup, }) => { const walletAddressUrl = process.env.TEST_WALLET_ADDRESS_URL; const playgroundUrl = 'https://webmonetization.org/play/'; - const monetizationCallback = await test.step('prepare', async () => { + await test.step('prepare', async () => { await expect(popup.getByTestId('not-monetized-message')).toBeVisible(); await page.goto(playgroundUrl); From 8329e57da9dc400643a10adbd1a417b98fa9699b Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Mon, 13 Jan 2025 18:33:04 +0530 Subject: [PATCH 5/7] fail safely correctly --- tests/e2e/special.spec.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/e2e/special.spec.ts b/tests/e2e/special.spec.ts index 5ff3f48e..da5dad02 100644 --- a/tests/e2e/special.spec.ts +++ b/tests/e2e/special.spec.ts @@ -71,6 +71,10 @@ test('iframe navigate does not de-monetize main page', async ({ page, popup, }) => { + test.fail( + true, + 'https://github.com/interledger/web-monetization-extension/issues/819', + ); const walletAddressUrl = process.env.TEST_WALLET_ADDRESS_URL; const playgroundUrl = 'https://webmonetization.org/play/'; @@ -118,10 +122,6 @@ test('iframe navigate does not de-monetize main page', async ({ }); }); - test.fail( - true, - 'https://github.com/interledger/web-monetization-extension/issues/819', - ); await test.step('navigate iframe', async () => { await page.evaluate(() => { return new Promise((resolve, reject) => { @@ -132,10 +132,11 @@ test('iframe navigate does not de-monetize main page', async ({ } iframe.addEventListener('load', resolve, { once: true }); iframe.addEventListener('error', resolve, { once: true }); - iframe.setAttribute('src', 'https://example.com/test'); + iframe.setAttribute('src', 'https://example.net'); }); }); + // this fails await expect(popup.getByTestId('not-monetized-message')).not.toBeVisible(); await expect(popup.getByTestId('home-page')).toBeVisible(); }); From 0eb8f7dbdab18a8b255c0381271f3a8120ba0648 Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Mon, 13 Jan 2025 18:50:18 +0530 Subject: [PATCH 6/7] `changeInfo.url` is set only actual tab navigation this fixes the issue --- src/background/services/tabEvents.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/background/services/tabEvents.ts b/src/background/services/tabEvents.ts index eca8e545..617a6fac 100644 --- a/src/background/services/tabEvents.ts +++ b/src/background/services/tabEvents.ts @@ -87,7 +87,7 @@ export class TabEvents { * if loading and no url -> clear all sessions but not the overpaying state * if loading and url -> we need to check if state keys include this url. */ - if (changeInfo.status === 'loading') { + if (changeInfo.status === 'loading' && changeInfo.url) { const url = tab.url ? removeQueryParams(tab.url) : ''; const clearOverpaying = this.tabState.shouldClearOverpaying(tabId, url); From 0d50cd29c657d63b7119bcff5d3dd2a76dc8e336 Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Mon, 13 Jan 2025 18:53:56 +0530 Subject: [PATCH 7/7] don't expect test to fail anymore --- tests/e2e/special.spec.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/e2e/special.spec.ts b/tests/e2e/special.spec.ts index da5dad02..4b312232 100644 --- a/tests/e2e/special.spec.ts +++ b/tests/e2e/special.spec.ts @@ -71,10 +71,6 @@ test('iframe navigate does not de-monetize main page', async ({ page, popup, }) => { - test.fail( - true, - 'https://github.com/interledger/web-monetization-extension/issues/819', - ); const walletAddressUrl = process.env.TEST_WALLET_ADDRESS_URL; const playgroundUrl = 'https://webmonetization.org/play/'; @@ -136,7 +132,6 @@ test('iframe navigate does not de-monetize main page', async ({ }); }); - // this fails await expect(popup.getByTestId('not-monetized-message')).not.toBeVisible(); await expect(popup.getByTestId('home-page')).toBeVisible(); });