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();
});