chore(ui): test that UI works behind proxy

This commit is contained in:
Simon Knott 2024-11-26 12:22:21 +01:00
parent 39285c4667
commit d9b2168172
No known key found for this signature in database
GPG key ID: 8CEDC00028084AEC
3 changed files with 119 additions and 0 deletions

62
package-lock.json generated
View file

@ -26,6 +26,7 @@
"@types/babel__core": "^7.20.2", "@types/babel__core": "^7.20.2",
"@types/codemirror": "^5.60.7", "@types/codemirror": "^5.60.7",
"@types/formidable": "^2.0.4", "@types/formidable": "^2.0.4",
"@types/http-proxy": "^1.17.15",
"@types/immutable": "^3.8.7", "@types/immutable": "^3.8.7",
"@types/node": "^18.19.39", "@types/node": "^18.19.39",
"@types/react": "^18.0.12", "@types/react": "^18.0.12",
@ -53,6 +54,7 @@
"eslint-plugin-react": "^7.35.0", "eslint-plugin-react": "^7.35.0",
"eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-hooks": "^4.6.2",
"formidable": "^2.1.1", "formidable": "^2.1.1",
"http-proxy": "^1.18.1",
"immutable": "^4.3.7", "immutable": "^4.3.7",
"license-checker": "^25.0.1", "license-checker": "^25.0.1",
"mime": "^3.0.0", "mime": "^3.0.0",
@ -1831,6 +1833,16 @@
"integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==",
"dev": true "dev": true
}, },
"node_modules/@types/http-proxy": {
"version": "1.17.15",
"resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz",
"integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/immutable": { "node_modules/@types/immutable": {
"version": "3.8.7", "version": "3.8.7",
"resolved": "https://registry.npmjs.org/@types/immutable/-/immutable-3.8.7.tgz", "resolved": "https://registry.npmjs.org/@types/immutable/-/immutable-3.8.7.tgz",
@ -3908,6 +3920,13 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/eventemitter3": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
"dev": true,
"license": "MIT"
},
"node_modules/extract-zip": { "node_modules/extract-zip": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
@ -4046,6 +4065,27 @@
"integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==",
"dev": true "dev": true
}, },
"node_modules/follow-redirects": {
"version": "1.15.9",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
"integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
"dev": true,
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"license": "MIT",
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/for-each": { "node_modules/for-each": {
"version": "0.3.3", "version": "0.3.3",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
@ -4527,6 +4567,21 @@
"integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==",
"dev": true "dev": true
}, },
"node_modules/http-proxy": {
"version": "1.18.1",
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
"integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"eventemitter3": "^4.0.0",
"follow-redirects": "^1.0.0",
"requires-port": "^1.0.0"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/http2-wrapper": { "node_modules/http2-wrapper": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz",
@ -6107,6 +6162,13 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
"dev": true,
"license": "MIT"
},
"node_modules/resolve": { "node_modules/resolve": {
"version": "2.0.0-next.5", "version": "2.0.0-next.5",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz",

View file

@ -65,6 +65,7 @@
"@types/babel__core": "^7.20.2", "@types/babel__core": "^7.20.2",
"@types/codemirror": "^5.60.7", "@types/codemirror": "^5.60.7",
"@types/formidable": "^2.0.4", "@types/formidable": "^2.0.4",
"@types/http-proxy": "^1.17.15",
"@types/immutable": "^3.8.7", "@types/immutable": "^3.8.7",
"@types/node": "^18.19.39", "@types/node": "^18.19.39",
"@types/react": "^18.0.12", "@types/react": "^18.0.12",
@ -92,6 +93,7 @@
"eslint-plugin-react": "^7.35.0", "eslint-plugin-react": "^7.35.0",
"eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-hooks": "^4.6.2",
"formidable": "^2.1.1", "formidable": "^2.1.1",
"http-proxy": "^1.18.1",
"immutable": "^4.3.7", "immutable": "^4.3.7",
"license-checker": "^25.0.1", "license-checker": "^25.0.1",
"mime": "^3.0.0", "mime": "^3.0.0",

View file

@ -16,6 +16,9 @@
import { createImage } from './playwright-test-fixtures'; import { createImage } from './playwright-test-fixtures';
import { test, expect, retries } from './ui-mode-fixtures'; import { test, expect, retries } from './ui-mode-fixtures';
import http from 'node:http';
import httpProxy from 'http-proxy';
import { ManualPromise } from 'packages/playwright-core/lib/utils/manualPromise';
test.describe.configure({ mode: 'parallel', retries }); test.describe.configure({ mode: 'parallel', retries });
@ -339,3 +342,55 @@ test('should show request source context id', async ({ runUITest, server }) => {
await expect(page.getByText('page#2')).toBeVisible(); await expect(page.getByText('page#2')).toBeVisible();
await expect(page.getByText('api#1')).toBeVisible(); await expect(page.getByText('api#1')).toBeVisible();
}); });
test('should work behind proxy', async ({ runUITest }, testInfo) => {
const { page } = await runUITest({
'a.test.ts': `
import { test, expect } from '@playwright/test';
test('trace test', async ({ page }) => {
await page.setContent('<button>Submit</button>');
await page.getByRole('button').click();
expect(1).toBe(1);
});
`,
});
const prefix = '/subdir';
const origin = new URL(page.url());
const proxy = httpProxy.createProxy({ target: { port: origin.port }, ws: true });
const proxyServer = http.createServer((req, res) => {
req.url = req.url!.replace(prefix, '');
proxy.web(req, res);
});
proxyServer.on('upgrade', (req, socket, head) => {
req.url = req.url!.replace(prefix, '');
proxy.ws(req, socket, head);
});
const proxyPort = 9010 + testInfo.workerIndex * 4;
await new Promise<void>(resolve => proxyServer.listen(proxyPort, resolve));
const proxyURL = new URL(origin);
proxyURL.host = `localhost:${proxyPort}`;
proxyURL.pathname = prefix + proxyURL.pathname;
await page.goto(proxyURL.toString());
await page.getByText('trace test').dblclick();
await expect(page.getByTestId('actions-tree')).toMatchAriaSnapshot(`
- tree:
- treeitem /Before Hooks \\d+[hmsp]+/
- treeitem /page\\.setContent \\d+[hmsp]+/
- treeitem /locator\\.clickgetByRole\\('button'\\) \\d+[hmsp]+/
- treeitem /expect\\.toBe \\d+[hmsp]+/ [selected]
- treeitem /After Hooks \\d+[hmsp]+/
`);
await expect(
page.frameLocator('iframe.snapshot-visible[name=snapshot]').locator('button'),
).toHaveText('Submit');
proxyServer.close();
});