mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
chore: implement a test runner on top of mocha (#8866)
* chore: implement a test runner on top of mocha This PR implements a test runner on top of mocha that performs multiple mocha runs as defined in TestSuites.json and compares the outcome of the runs against TestExpectations.json. This allows us to remove most of helpers from mocha-utils and be more flexible when defining the test configurations.
This commit is contained in:
parent
f02b926245
commit
d8830cbc55
22
.github/workflows/ci.yml
vendored
22
.github/workflows/ci.yml
vendored
@ -173,26 +173,12 @@ jobs:
|
||||
run: npm run build:dev
|
||||
- name: Test types
|
||||
run: npm run test:types
|
||||
# On Linux we run all Chrome tests without retries and Firefox tests with retries.
|
||||
- name: Run all Chrome tests (only on Linux)
|
||||
- name: Run all tests with xvfb
|
||||
if: ${{ matrix.spec.name == 'Linux' }}
|
||||
run: xvfb-run --auto-servernum npm run test:chrome
|
||||
- name: Run all Firefox tests (only on Linux)
|
||||
if: ${{ matrix.spec.name == 'Linux' }}
|
||||
uses: nick-invision/retry@v2
|
||||
with:
|
||||
command: xvfb-run --auto-servernum npm run test:firefox
|
||||
timeout_minutes: 20
|
||||
max_attempts: 3
|
||||
# On other platforms we only run chrome:headless tests and continue on Firefox errors.
|
||||
- name: Test Chrome Headless (not on Linux)
|
||||
id: test-chrome
|
||||
run: xvfb-run --auto-servernum npm run test
|
||||
- name: Run all tests without xvfb
|
||||
if: ${{ matrix.spec.name != 'Linux' }}
|
||||
run: npm run test:chrome:headless
|
||||
- name: Run all Firefox tests (not on Linux)
|
||||
if: ${{ matrix.spec.name != 'Linux' }}
|
||||
continue-on-error: true
|
||||
run: npm run test:firefox
|
||||
run: npm run test
|
||||
- name: Test bundling and installation
|
||||
if: ${{ matrix.spec.name == 'Linux' }}
|
||||
run: |
|
||||
|
@ -22,6 +22,6 @@ module.exports = {
|
||||
exit: !!process.env.CI,
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
parallel: !!process.env.PARALLEL,
|
||||
timeout: 25 * 1000,
|
||||
timeout: 25_000,
|
||||
reporter: process.env.CI ? 'spec' : 'dot',
|
||||
};
|
||||
|
18
package-lock.json
generated
18
package-lock.json
generated
@ -80,7 +80,8 @@
|
||||
"text-diff": "1.0.1",
|
||||
"tsd": "0.22.0",
|
||||
"tsx": "3.8.2",
|
||||
"typescript": "4.7.4"
|
||||
"typescript": "4.7.4",
|
||||
"zod": "3.18.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.1.0"
|
||||
@ -7809,6 +7810,15 @@
|
||||
"optionalDependencies": {
|
||||
"commander": "^2.20.3"
|
||||
}
|
||||
},
|
||||
"node_modules/zod": {
|
||||
"version": "3.18.0",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.18.0.tgz",
|
||||
"integrity": "sha512-gwTm8RfUCe8l9rDwN5r2A17DkAa8Ez4Yl4yXqc5VqeGaXaJahzYYXbTwvhroZi0SNBqTwh/bKm2N0mpCzuw4bA==",
|
||||
"dev": true,
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
@ -13501,6 +13511,12 @@
|
||||
"lodash.isequal": "^4.5.0",
|
||||
"validator": "^13.7.0"
|
||||
}
|
||||
},
|
||||
"zod": {
|
||||
"version": "3.18.0",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.18.0.tgz",
|
||||
"integrity": "sha512-gwTm8RfUCe8l9rDwN5r2A17DkAa8Ez4Yl4yXqc5VqeGaXaJahzYYXbTwvhroZi0SNBqTwh/bKm2N0mpCzuw4bA==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
13
package.json
13
package.json
@ -27,14 +27,14 @@
|
||||
"node": ">=14.1.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "c8 --check-coverage --lines 93 run-s test:chrome:* test:firefox",
|
||||
"test": "cross-env MOZ_WEBRENDER=0 PUPPETEER_DEFERRED_PROMISE_DEBUG_TIMEOUT=20000 c8 --check-coverage --lines 93 node utils/mochaRunner/lib/main.js",
|
||||
"test:types": "tsd",
|
||||
"test:install": "scripts/test-install.sh",
|
||||
"test:firefox": "cross-env PUPPETEER_PRODUCT=firefox MOZ_WEBRENDER=0 PUPPETEER_DEFERRED_PROMISE_DEBUG_TIMEOUT=20000 mocha",
|
||||
"test:firefox": "npm run test -- --test-suite firefox-headless",
|
||||
"test:chrome": "run-s test:chrome:*",
|
||||
"test:chrome:headless": "cross-env HEADLESS=true PUPPETEER_DEFERRED_PROMISE_DEBUG_TIMEOUT=20000 mocha",
|
||||
"test:chrome:headless-chrome": "cross-env HEADLESS=chrome PUPPETEER_DEFERRED_PROMISE_DEBUG_TIMEOUT=20000 mocha",
|
||||
"test:chrome:headful": "cross-env HEADLESS=false PUPPETEER_DEFERRED_PROMISE_DEBUG_TIMEOUT=20000 mocha",
|
||||
"test:chrome:headless": "npm run test -- --test-suite chrome-headless",
|
||||
"test:chrome:headless-chrome": "npm run test -- --test-suite chrome-new-headless",
|
||||
"test:chrome:headful": "npm run test -- --test-suite chrome-headful",
|
||||
"prepublishOnly": "npm run build",
|
||||
"prepare": "node typescript-if-required.js && husky install",
|
||||
"lint": "run-s lint:prettier lint:eslint",
|
||||
@ -139,6 +139,7 @@
|
||||
"text-diff": "1.0.1",
|
||||
"tsd": "0.22.0",
|
||||
"tsx": "3.8.2",
|
||||
"typescript": "4.7.4"
|
||||
"typescript": "4.7.4",
|
||||
"zod": "3.18.0"
|
||||
}
|
||||
}
|
||||
|
1946
test/TestExpectations.json
Normal file
1946
test/TestExpectations.json
Normal file
File diff suppressed because it is too large
Load Diff
41
test/TestSuites.json
Normal file
41
test/TestSuites.json
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"testSuites": [
|
||||
{
|
||||
"id": "chrome-headless",
|
||||
"platforms": ["linux", "win32", "darwin"],
|
||||
"parameters": ["chrome", "headless"]
|
||||
},
|
||||
{
|
||||
"id": "chrome-headful",
|
||||
"platforms": ["linux"],
|
||||
"parameters": ["chrome", "headful"]
|
||||
},
|
||||
{
|
||||
"id": "chrome-new-headless",
|
||||
"platforms": ["linux"],
|
||||
"parameters": ["chrome", "chrome-headless"]
|
||||
},
|
||||
{
|
||||
"id": "firefox-headless",
|
||||
"platforms": ["linux"],
|
||||
"parameters": ["firefox", "headless"]
|
||||
}
|
||||
],
|
||||
"parameterDefinitons": {
|
||||
"chrome": {
|
||||
"PUPPETEER_PRODUCT": "chrome"
|
||||
},
|
||||
"firefox": {
|
||||
"PUPPETEER_PRODUCT": "firefox"
|
||||
},
|
||||
"headless": {
|
||||
"HEADLESS": "true"
|
||||
},
|
||||
"headful": {
|
||||
"HEADLESS": "false"
|
||||
},
|
||||
"chrome-headless": {
|
||||
"HEADLESS": "chrome"
|
||||
}
|
||||
}
|
||||
}
|
@ -20,11 +20,11 @@ import {
|
||||
getTestState,
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
describeChromeOnly,
|
||||
} from './mocha-utils.js';
|
||||
import {isErrorLike} from '../../lib/cjs/puppeteer/util/ErrorLike.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describeChromeOnly('Target.createCDPSession', function () {
|
||||
describe('Target.createCDPSession', function () {
|
||||
setupTestBrowserHooks();
|
||||
setupTestPageAndContextHooks();
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
import {EventEmitter} from '../../lib/cjs/puppeteer/common/EventEmitter.js';
|
||||
import sinon from 'sinon';
|
||||
import expect from 'expect';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describe('EventEmitter', () => {
|
||||
let emitter: EventEmitter;
|
||||
|
@ -14,8 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {describeChromeOnly} from './mocha-utils.js';
|
||||
|
||||
import expect from 'expect';
|
||||
import {
|
||||
NetworkManager,
|
||||
@ -25,12 +23,13 @@ import {HTTPRequest} from '../../lib/cjs/puppeteer/common/HTTPRequest.js';
|
||||
import {EventEmitter} from '../../lib/cjs/puppeteer/common/EventEmitter.js';
|
||||
import {Frame} from '../../lib/cjs/puppeteer/common/Frame.js';
|
||||
import {HTTPResponse} from '../../lib/cjs/puppeteer/common/HTTPResponse.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
class MockCDPSession extends EventEmitter {
|
||||
async send(): Promise<any> {}
|
||||
}
|
||||
|
||||
describeChromeOnly('NetworkManager', () => {
|
||||
describe('NetworkManager', () => {
|
||||
it('should process extra info on multiple redirects', async () => {
|
||||
const mockCDPSession = new MockCDPSession();
|
||||
new NetworkManager(mockCDPSession, true, {
|
||||
|
@ -14,8 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {describeChromeOnly, getTestState} from './mocha-utils'; // eslint-disable-line import/extensions
|
||||
import {getTestState} from './mocha-utils'; // eslint-disable-line import/extensions
|
||||
import utils from './utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
import expect from 'expect';
|
||||
|
||||
@ -24,7 +25,7 @@ import {
|
||||
BrowserContext,
|
||||
} from '../../lib/cjs/puppeteer/common/Browser.js';
|
||||
|
||||
describeChromeOnly('TargetManager', () => {
|
||||
describe('TargetManager', () => {
|
||||
/* We use a special browser for this test as we need the --site-per-process flag */
|
||||
let browser: Browser;
|
||||
let context: BrowserContext;
|
||||
|
@ -21,10 +21,10 @@ import {
|
||||
getTestState,
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
describeFailsFirefox,
|
||||
} from './mocha-utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describeFailsFirefox('Accessibility', function () {
|
||||
describe('Accessibility', function () {
|
||||
setupTestBrowserHooks();
|
||||
setupTestPageAndContextHooks();
|
||||
|
||||
@ -346,7 +346,7 @@ describeFailsFirefox('Accessibility', function () {
|
||||
});
|
||||
|
||||
// Firefox does not support contenteditable="plaintext-only".
|
||||
describeFailsFirefox('plaintext contenteditable', function () {
|
||||
describe('plaintext contenteditable', function () {
|
||||
it('plain text field with role should not have children', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
|
@ -19,14 +19,14 @@ import {
|
||||
getTestState,
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
describeChromeOnly,
|
||||
} from './mocha-utils.js';
|
||||
|
||||
import {ElementHandle} from '../../lib/cjs/puppeteer/common/ElementHandle.js';
|
||||
import utils from './utils.js';
|
||||
import assert from 'assert';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describeChromeOnly('AriaQueryHandler', () => {
|
||||
describe('AriaQueryHandler', () => {
|
||||
setupTestBrowserHooks();
|
||||
setupTestPageAndContextHooks();
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
import expect from 'expect';
|
||||
import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describe('Browser specs', function () {
|
||||
setupTestBrowserHooks();
|
||||
|
@ -15,12 +15,9 @@
|
||||
*/
|
||||
|
||||
import expect from 'expect';
|
||||
import {
|
||||
getTestState,
|
||||
itFailsFirefox,
|
||||
setupTestBrowserHooks,
|
||||
} from './mocha-utils.js';
|
||||
import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
|
||||
import {waitEvent} from './utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describe('BrowserContext', function () {
|
||||
setupTestBrowserHooks();
|
||||
@ -60,7 +57,7 @@ describe('BrowserContext', function () {
|
||||
await context.close();
|
||||
expect((await browser.pages()).length).toBe(1);
|
||||
});
|
||||
itFailsFirefox('window.open should use parent tab context', async () => {
|
||||
it('window.open should use parent tab context', async () => {
|
||||
const {browser, server} = getTestState();
|
||||
|
||||
const context = await browser.createIncognitoBrowserContext();
|
||||
@ -75,7 +72,7 @@ describe('BrowserContext', function () {
|
||||
expect(popupTarget.browserContext()).toBe(context);
|
||||
await context.close();
|
||||
});
|
||||
itFailsFirefox('should fire target events', async () => {
|
||||
it('should fire target events', async () => {
|
||||
const {browser, server} = getTestState();
|
||||
|
||||
const context = await browser.createIncognitoBrowserContext();
|
||||
@ -99,7 +96,7 @@ describe('BrowserContext', function () {
|
||||
]);
|
||||
await context.close();
|
||||
});
|
||||
itFailsFirefox('should wait for a target', async () => {
|
||||
it('should wait for a target', async () => {
|
||||
const {browser, puppeteer, server} = getTestState();
|
||||
|
||||
const context = await browser.createIncognitoBrowserContext();
|
||||
@ -156,7 +153,7 @@ describe('BrowserContext', function () {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
itFailsFirefox('should isolate localStorage and cookies', async () => {
|
||||
it('should isolate localStorage and cookies', async () => {
|
||||
const {browser, server} = getTestState();
|
||||
|
||||
// Create two incognito contexts.
|
||||
@ -216,7 +213,7 @@ describe('BrowserContext', function () {
|
||||
expect(browser.browserContexts().length).toBe(1);
|
||||
});
|
||||
|
||||
itFailsFirefox('should work across sessions', async () => {
|
||||
it('should work across sessions', async () => {
|
||||
const {browser, puppeteer} = getTestState();
|
||||
|
||||
expect(browser.browserContexts().length).toBe(1);
|
||||
|
@ -19,10 +19,10 @@ import {
|
||||
getTestState,
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
describeChromeOnly,
|
||||
} from './mocha-utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describeChromeOnly('Chromium-Specific Launcher tests', function () {
|
||||
describe('Chromium-Specific Launcher tests', function () {
|
||||
describe('Puppeteer.launch |browserURL| option', function () {
|
||||
it('should be able to connect using browserUrl, with and without trailing slash', async () => {
|
||||
const {defaultBrowserOptions, puppeteer} = getTestState();
|
||||
@ -138,7 +138,7 @@ describeChromeOnly('Chromium-Specific Launcher tests', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeChromeOnly('Chromium-Specific Page Tests', function () {
|
||||
describe('Chromium-Specific Page Tests', function () {
|
||||
setupTestBrowserHooks();
|
||||
setupTestPageAndContextHooks();
|
||||
it('Page.setRequestInterception should work with intervention headers', async () => {
|
||||
|
@ -19,9 +19,9 @@ import {
|
||||
getTestState,
|
||||
setupTestPageAndContextHooks,
|
||||
setupTestBrowserHooks,
|
||||
itFailsFirefox,
|
||||
} from './mocha-utils.js';
|
||||
import utils from './utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describe('Page.click', function () {
|
||||
setupTestBrowserHooks();
|
||||
@ -52,9 +52,7 @@ describe('Page.click', function () {
|
||||
})
|
||||
).toBe(42);
|
||||
});
|
||||
itFailsFirefox(
|
||||
'should click the button if window.Node is removed',
|
||||
async () => {
|
||||
it('should click the button if window.Node is removed', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
@ -68,8 +66,7 @@ describe('Page.click', function () {
|
||||
return (globalThis as any).result;
|
||||
})
|
||||
).toBe('Clicked');
|
||||
}
|
||||
);
|
||||
});
|
||||
// @see https://github.com/puppeteer/puppeteer/issues/4281
|
||||
it('should click on a span with an inline element inside', async () => {
|
||||
const {page} = getTestState();
|
||||
@ -110,7 +107,7 @@ describe('Page.click', function () {
|
||||
})
|
||||
).toBe('Clicked');
|
||||
});
|
||||
itFailsFirefox('should click with disabled javascript', async () => {
|
||||
it('should click with disabled javascript', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.setJavaScriptEnabled(false);
|
||||
@ -240,7 +237,7 @@ describe('Page.click', function () {
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
itFailsFirefox('should click on checkbox label and toggle', async () => {
|
||||
it('should click on checkbox label and toggle', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/input/checkbox.html');
|
||||
|
@ -19,8 +19,8 @@ import {
|
||||
getTestState,
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
itFailsFirefox,
|
||||
} from './mocha-utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describe('Cookie specs', () => {
|
||||
setupTestBrowserHooks();
|
||||
@ -128,7 +128,7 @@ describe('Cookie specs', () => {
|
||||
},
|
||||
]);
|
||||
});
|
||||
itFailsFirefox('should get cookies from multiple urls', async () => {
|
||||
it('should get cookies from multiple urls', async () => {
|
||||
const {page} = getTestState();
|
||||
await page.setCookie(
|
||||
{
|
||||
@ -184,7 +184,7 @@ describe('Cookie specs', () => {
|
||||
});
|
||||
});
|
||||
describe('Page.setCookie', function () {
|
||||
itFailsFirefox('should work', async () => {
|
||||
it('should work', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -198,7 +198,7 @@ describe('Cookie specs', () => {
|
||||
})
|
||||
).toEqual('password=123456');
|
||||
});
|
||||
itFailsFirefox('should isolate cookies in browser contexts', async () => {
|
||||
it('should isolate cookies in browser contexts', async () => {
|
||||
const {page, server, browser} = getTestState();
|
||||
|
||||
const anotherContext = await browser.createIncognitoBrowserContext();
|
||||
@ -220,7 +220,7 @@ describe('Cookie specs', () => {
|
||||
expect(cookies2[0]!.value).toBe('page2value');
|
||||
await anotherContext.close();
|
||||
});
|
||||
itFailsFirefox('should set multiple cookies', async () => {
|
||||
it('should set multiple cookies', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -257,7 +257,7 @@ describe('Cookie specs', () => {
|
||||
expect(cookies[0]!.session).toBe(true);
|
||||
expect(cookies[0]!.expires).toBe(-1);
|
||||
});
|
||||
itFailsFirefox('should set cookie with reasonable defaults', async () => {
|
||||
it('should set cookie with reasonable defaults', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -288,7 +288,7 @@ describe('Cookie specs', () => {
|
||||
]
|
||||
);
|
||||
});
|
||||
itFailsFirefox('should set a cookie with a path', async () => {
|
||||
it('should set a cookie with a path', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
@ -365,9 +365,7 @@ describe('Cookie specs', () => {
|
||||
'At least one of the url and domain needs to be specified'
|
||||
);
|
||||
});
|
||||
itFailsFirefox(
|
||||
'should default to setting secure cookie for HTTPS websites',
|
||||
async () => {
|
||||
it('should default to setting secure cookie for HTTPS websites', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -379,8 +377,7 @@ describe('Cookie specs', () => {
|
||||
});
|
||||
const [cookie] = await page.cookies(SECURE_URL);
|
||||
expect(cookie!.secure).toBe(true);
|
||||
}
|
||||
);
|
||||
});
|
||||
it('should be able to set unsecure cookie for HTTP website', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -394,7 +391,7 @@ describe('Cookie specs', () => {
|
||||
const [cookie] = await page.cookies(HTTP_URL);
|
||||
expect(cookie!.secure).toBe(false);
|
||||
});
|
||||
itFailsFirefox('should set a cookie on a different domain', async () => {
|
||||
it('should set a cookie on a different domain', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -422,7 +419,7 @@ describe('Cookie specs', () => {
|
||||
},
|
||||
]);
|
||||
});
|
||||
itFailsFirefox('should set cookies from a frame', async () => {
|
||||
it('should set cookies from a frame', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
@ -482,9 +479,7 @@ describe('Cookie specs', () => {
|
||||
},
|
||||
]);
|
||||
});
|
||||
itFailsFirefox(
|
||||
'should set secure same-site cookies from a frame',
|
||||
async () => {
|
||||
it('should set secure same-site cookies from a frame', async () => {
|
||||
const {httpsServer, puppeteer, defaultBrowserOptions} = getTestState();
|
||||
|
||||
const browser = await puppeteer.launch({
|
||||
@ -541,12 +536,11 @@ describe('Cookie specs', () => {
|
||||
await page.close();
|
||||
await browser.close();
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Page.deleteCookie', function () {
|
||||
itFailsFirefox('should work', async () => {
|
||||
it('should work', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
|
@ -19,11 +19,11 @@ import {
|
||||
getTestState,
|
||||
setupTestPageAndContextHooks,
|
||||
setupTestBrowserHooks,
|
||||
describeChromeOnly,
|
||||
} from './mocha-utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describe('Coverage specs', function () {
|
||||
describeChromeOnly('JSCoverage', function () {
|
||||
describe('JSCoverage', function () {
|
||||
setupTestBrowserHooks();
|
||||
setupTestPageAndContextHooks();
|
||||
|
||||
@ -202,7 +202,7 @@ describe('Coverage specs', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeChromeOnly('CSSCoverage', function () {
|
||||
describe('CSSCoverage', function () {
|
||||
setupTestBrowserHooks();
|
||||
setupTestPageAndContextHooks();
|
||||
|
||||
|
@ -19,8 +19,8 @@ import {
|
||||
getTestState,
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
itFailsFirefox,
|
||||
} from './mocha-utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describe('DefaultBrowserContext', function () {
|
||||
setupTestBrowserHooks();
|
||||
@ -48,7 +48,7 @@ describe('DefaultBrowserContext', function () {
|
||||
},
|
||||
]);
|
||||
});
|
||||
itFailsFirefox('page.setCookie() should work', async () => {
|
||||
it('page.setCookie() should work', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -78,7 +78,7 @@ describe('DefaultBrowserContext', function () {
|
||||
},
|
||||
]);
|
||||
});
|
||||
itFailsFirefox('page.deleteCookie() should work', async () => {
|
||||
it('page.deleteCookie() should work', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
|
@ -20,8 +20,8 @@ import {
|
||||
getTestState,
|
||||
setupTestPageAndContextHooks,
|
||||
setupTestBrowserHooks,
|
||||
itFailsFirefox,
|
||||
} from './mocha-utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describe('Page.Events.Dialog', function () {
|
||||
setupTestBrowserHooks();
|
||||
@ -46,7 +46,7 @@ describe('Page.Events.Dialog', function () {
|
||||
expect(dialog.message()).toBe('yo');
|
||||
});
|
||||
|
||||
itFailsFirefox('should allow accepting prompts', async () => {
|
||||
it('should allow accepting prompts', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
const onDialog = sinon.stub().callsFake(dialog => {
|
||||
|
@ -19,10 +19,10 @@ import {
|
||||
getTestState,
|
||||
setupTestPageAndContextHooks,
|
||||
setupTestBrowserHooks,
|
||||
describeChromeOnly,
|
||||
} from './mocha-utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describeChromeOnly('Input.drag', function () {
|
||||
describe('Input.drag', function () {
|
||||
setupTestBrowserHooks();
|
||||
setupTestPageAndContextHooks();
|
||||
it('should throw an exception if not enabled before usage', async () => {
|
||||
|
@ -18,12 +18,11 @@ import expect from 'expect';
|
||||
import sinon from 'sinon';
|
||||
import {ElementHandle} from '../../lib/cjs/puppeteer/common/ElementHandle.js';
|
||||
import {
|
||||
describeFailsFirefox,
|
||||
getTestState,
|
||||
itFailsFirefox,
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
} from './mocha-utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
import utils from './utils.js';
|
||||
|
||||
@ -31,7 +30,7 @@ describe('ElementHandle specs', function () {
|
||||
setupTestBrowserHooks();
|
||||
setupTestPageAndContextHooks();
|
||||
|
||||
describeFailsFirefox('ElementHandle.boundingBox', function () {
|
||||
describe('ElementHandle.boundingBox', function () {
|
||||
it('should work', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -96,7 +95,7 @@ describe('ElementHandle specs', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('ElementHandle.boxModel', function () {
|
||||
describe('ElementHandle.boxModel', function () {
|
||||
it('should work', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -162,7 +161,7 @@ describe('ElementHandle specs', function () {
|
||||
});
|
||||
|
||||
describe('ElementHandle.contentFrame', function () {
|
||||
itFailsFirefox('should work', async () => {
|
||||
it('should work', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -175,7 +174,7 @@ describe('ElementHandle specs', function () {
|
||||
|
||||
describe('ElementHandle.click', function () {
|
||||
// See https://github.com/puppeteer/puppeteer/issues/7175
|
||||
itFailsFirefox('should work', async () => {
|
||||
it('should work', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
|
@ -20,9 +20,8 @@ import {
|
||||
getTestState,
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
itFailsFirefox,
|
||||
describeFailsFirefox,
|
||||
} from './mocha-utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describe('Emulation', () => {
|
||||
setupTestBrowserHooks();
|
||||
@ -132,7 +131,7 @@ describe('Emulation', () => {
|
||||
})
|
||||
).toBe(true);
|
||||
});
|
||||
itFailsFirefox('should support landscape emulation', async () => {
|
||||
it('should support landscape emulation', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/mobile.html');
|
||||
@ -173,7 +172,7 @@ describe('Emulation', () => {
|
||||
})
|
||||
).toContain('iPhone');
|
||||
});
|
||||
itFailsFirefox('should support clicking', async () => {
|
||||
it('should support clicking', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.emulate(iPhone);
|
||||
@ -192,7 +191,7 @@ describe('Emulation', () => {
|
||||
});
|
||||
|
||||
describe('Page.emulateMediaType', function () {
|
||||
itFailsFirefox('should work', async () => {
|
||||
it('should work', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
expect(
|
||||
@ -240,7 +239,7 @@ describe('Emulation', () => {
|
||||
});
|
||||
|
||||
describe('Page.emulateMediaFeatures', function () {
|
||||
itFailsFirefox('should work', async () => {
|
||||
it('should work', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
await page.emulateMediaFeatures([
|
||||
@ -370,7 +369,7 @@ describe('Emulation', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Page.emulateTimezone', function () {
|
||||
describe('Page.emulateTimezone', function () {
|
||||
it('should work', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
@ -425,7 +424,7 @@ describe('Emulation', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Page.emulateVisionDeficiency', function () {
|
||||
describe('Page.emulateVisionDeficiency', function () {
|
||||
it('should work', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -489,7 +488,7 @@ describe('Emulation', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Page.emulateNetworkConditions', function () {
|
||||
describe('Page.emulateNetworkConditions', function () {
|
||||
it('should change navigator.connection.effectiveType', async () => {
|
||||
const {page, puppeteer} = getTestState();
|
||||
|
||||
@ -511,7 +510,7 @@ describe('Emulation', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Page.emulateCPUThrottling', function () {
|
||||
describe('Page.emulateCPUThrottling', function () {
|
||||
it('should change the CPU throttling rate successfully', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
|
@ -20,9 +20,8 @@ import {
|
||||
getTestState,
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
itFailsFirefox,
|
||||
describeFailsFirefox,
|
||||
} from './mocha-utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
const bigint = typeof BigInt !== 'undefined';
|
||||
|
||||
@ -115,9 +114,7 @@ describe('Evaluation specs', function () {
|
||||
await page.goto(server.PREFIX + '/global-var.html');
|
||||
expect(await page.evaluate('globalVar')).toBe(123);
|
||||
});
|
||||
itFailsFirefox(
|
||||
'should return undefined for objects with symbols',
|
||||
async () => {
|
||||
it('should return undefined for objects with symbols', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
expect(
|
||||
@ -125,8 +122,7 @@ describe('Evaluation specs', function () {
|
||||
return [Symbol('foo4')];
|
||||
})
|
||||
).toBe(undefined);
|
||||
}
|
||||
);
|
||||
});
|
||||
it('should work with function shorthands', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
@ -155,7 +151,7 @@ describe('Evaluation specs', function () {
|
||||
);
|
||||
expect(result).toBe(42);
|
||||
});
|
||||
itFailsFirefox('should throw when evaluation triggers reload', async () => {
|
||||
it('should throw when evaluation triggers reload', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
let error!: Error;
|
||||
@ -189,7 +185,7 @@ describe('Evaluation specs', function () {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
expect(await frameEvaluation).toBe(42);
|
||||
});
|
||||
itFailsFirefox('should work from-inside an exposed function', async () => {
|
||||
it('should work from-inside an exposed function', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
// Setup inpage callback, which calls Page.evaluate
|
||||
@ -324,9 +320,7 @@ describe('Evaluation specs', function () {
|
||||
})
|
||||
).toEqual({});
|
||||
});
|
||||
itFailsFirefox(
|
||||
'should return undefined for non-serializable objects',
|
||||
async () => {
|
||||
it('should return undefined for non-serializable objects', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
expect(
|
||||
@ -334,9 +328,8 @@ describe('Evaluation specs', function () {
|
||||
return window;
|
||||
})
|
||||
).toBe(undefined);
|
||||
}
|
||||
);
|
||||
itFailsFirefox('should fail for circular object', async () => {
|
||||
});
|
||||
it('should fail for circular object', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
const result = await page.evaluate(() => {
|
||||
@ -347,7 +340,7 @@ describe('Evaluation specs', function () {
|
||||
});
|
||||
expect(result).toBe(undefined);
|
||||
});
|
||||
itFailsFirefox('should be able to throw a tricky error', async () => {
|
||||
it('should be able to throw a tricky error', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
const windowHandle = await page.evaluateHandle(() => {
|
||||
@ -410,9 +403,7 @@ describe('Evaluation specs', function () {
|
||||
});
|
||||
expect(error.message).toContain('JSHandle is disposed');
|
||||
});
|
||||
itFailsFirefox(
|
||||
'should throw if elementHandles are from other frames',
|
||||
async () => {
|
||||
it('should throw if elementHandles are from other frames', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
|
||||
@ -429,9 +420,8 @@ describe('Evaluation specs', function () {
|
||||
expect(error.message).toContain(
|
||||
'JSHandles can be evaluated only in the context they were created'
|
||||
);
|
||||
}
|
||||
);
|
||||
itFailsFirefox('should simulate a user gesture', async () => {
|
||||
});
|
||||
it('should simulate a user gesture', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
const result = await page.evaluate(() => {
|
||||
@ -441,7 +431,7 @@ describe('Evaluation specs', function () {
|
||||
});
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
itFailsFirefox('should throw a nice error after a navigation', async () => {
|
||||
it('should throw a nice error after a navigation', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
const executionContext = await page.mainFrame().executionContext();
|
||||
@ -461,9 +451,7 @@ describe('Evaluation specs', function () {
|
||||
});
|
||||
expect((error as Error).message).toContain('navigation');
|
||||
});
|
||||
itFailsFirefox(
|
||||
'should not throw an error when evaluation does a navigation',
|
||||
async () => {
|
||||
it('should not throw an error when evaluation does a navigation', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/one-style.html');
|
||||
@ -472,8 +460,7 @@ describe('Evaluation specs', function () {
|
||||
return [42];
|
||||
});
|
||||
expect(result).toEqual([42]);
|
||||
}
|
||||
);
|
||||
});
|
||||
it('should transfer 100Mb of data from page to node.js', async function () {
|
||||
const {page} = getTestState();
|
||||
|
||||
@ -499,7 +486,7 @@ describe('Evaluation specs', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Page.evaluateOnNewDocument', function () {
|
||||
describe('Page.evaluateOnNewDocument', function () {
|
||||
it('should evaluate before anything else on the page', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
|
@ -17,12 +17,13 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
|
||||
import expect from 'expect';
|
||||
import {getTestState, itHeadlessOnly} from './mocha-utils.js';
|
||||
import {getTestState} from './mocha-utils.js';
|
||||
|
||||
import path from 'path';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describe('Fixtures', function () {
|
||||
itHeadlessOnly('dumpio option should work with pipe option', async () => {
|
||||
it('dumpio option should work with pipe option', async () => {
|
||||
const {defaultBrowserOptions, puppeteerPath, headless} = getTestState();
|
||||
if (headless === 'chrome') {
|
||||
// This test only works in the old headless mode.
|
||||
|
@ -19,18 +19,18 @@ import {CDPSession} from '../../lib/cjs/puppeteer/common/Connection.js';
|
||||
import {Frame} from '../../lib/cjs/puppeteer/common/Frame.js';
|
||||
import {
|
||||
getTestState,
|
||||
itFailsFirefox,
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
} from './mocha-utils.js';
|
||||
import utils, {dumpFrames} from './utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describe('Frame specs', function () {
|
||||
setupTestBrowserHooks();
|
||||
setupTestPageAndContextHooks();
|
||||
|
||||
describe('Frame.executionContext', function () {
|
||||
itFailsFirefox('should work', async () => {
|
||||
it('should work', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -80,7 +80,7 @@ describe('Frame specs', function () {
|
||||
});
|
||||
|
||||
describe('Frame.evaluate', function () {
|
||||
itFailsFirefox('should throw for detached frames', async () => {
|
||||
it('should throw for detached frames', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
const frame1 = (await utils.attachFrame(
|
||||
@ -126,7 +126,7 @@ describe('Frame specs', function () {
|
||||
});
|
||||
|
||||
describe('Frame Management', function () {
|
||||
itFailsFirefox('should handle nested frames', async () => {
|
||||
it('should handle nested frames', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/frames/nested-frames.html');
|
||||
@ -138,9 +138,7 @@ describe('Frame specs', function () {
|
||||
' http://localhost:<PORT>/frames/frame.html (aframe)',
|
||||
]);
|
||||
});
|
||||
itFailsFirefox(
|
||||
'should send events when frames are manipulated dynamically',
|
||||
async () => {
|
||||
it('should send events when frames are manipulated dynamically', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -170,8 +168,7 @@ describe('Frame specs', function () {
|
||||
await utils.detachFrame(page, 'frame1');
|
||||
expect(detachedFrames.length).toBe(1);
|
||||
expect(detachedFrames[0]!.isDetached()).toBe(true);
|
||||
}
|
||||
);
|
||||
});
|
||||
it('should send "framenavigated" when navigating on anchor URLs', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -259,7 +256,7 @@ describe('Frame specs', function () {
|
||||
expect(detachedFrames.length).toBe(4);
|
||||
expect(navigatedFrames.length).toBe(1);
|
||||
});
|
||||
itFailsFirefox('should report frame from-inside shadow DOM', async () => {
|
||||
it('should report frame from-inside shadow DOM', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/shadow.html');
|
||||
@ -274,7 +271,7 @@ describe('Frame specs', function () {
|
||||
expect(page.frames().length).toBe(2);
|
||||
expect(page.frames()[1]!.url()).toBe(server.EMPTY_PAGE);
|
||||
});
|
||||
itFailsFirefox('should report frame.name()', async () => {
|
||||
it('should report frame.name()', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await utils.attachFrame(page, 'theFrameId', server.EMPTY_PAGE);
|
||||
@ -291,7 +288,7 @@ describe('Frame specs', function () {
|
||||
expect(page.frames()[1]!.name()).toBe('theFrameId');
|
||||
expect(page.frames()[2]!.name()).toBe('theFrameName');
|
||||
});
|
||||
itFailsFirefox('should report frame.parent()', async () => {
|
||||
it('should report frame.parent()', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
|
||||
@ -300,16 +297,10 @@ describe('Frame specs', function () {
|
||||
expect(page.frames()[1]!.parentFrame()).toBe(page.mainFrame());
|
||||
expect(page.frames()[2]!.parentFrame()).toBe(page.mainFrame());
|
||||
});
|
||||
itFailsFirefox(
|
||||
'should report different frame instance when frame re-attaches',
|
||||
async () => {
|
||||
it('should report different frame instance when frame re-attaches', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
const frame1 = await utils.attachFrame(
|
||||
page,
|
||||
'frame1',
|
||||
server.EMPTY_PAGE
|
||||
);
|
||||
const frame1 = await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
|
||||
await page.evaluate(() => {
|
||||
(globalThis as any).frame = document.querySelector('#frame1');
|
||||
(globalThis as any).frame.remove();
|
||||
@ -323,8 +314,7 @@ describe('Frame specs', function () {
|
||||
]);
|
||||
expect(frame2.isDetached()).toBe(false);
|
||||
expect(frame1).not.toBe(frame2);
|
||||
}
|
||||
);
|
||||
});
|
||||
it('should support url fragment', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -335,7 +325,7 @@ describe('Frame specs', function () {
|
||||
server.PREFIX + '/frames/frame.html?param=value#fragment'
|
||||
);
|
||||
});
|
||||
itFailsFirefox('should support lazy frames', async () => {
|
||||
it('should support lazy frames', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.setViewport({width: 1000, height: 1000});
|
||||
|
@ -24,11 +24,8 @@ import {
|
||||
PuppeteerLaunchOptions,
|
||||
PuppeteerNode,
|
||||
} from '../../lib/cjs/puppeteer/node/Puppeteer.js';
|
||||
import {
|
||||
describeChromeOnly,
|
||||
getTestState,
|
||||
itFailsWindows,
|
||||
} from './mocha-utils.js';
|
||||
import {getTestState} from './mocha-utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
const rmAsync = promisify(rimraf);
|
||||
const mkdtempAsync = promisify(fs.mkdtemp);
|
||||
@ -44,7 +41,7 @@ const serviceWorkerExtensionPath = path.join(
|
||||
'extension'
|
||||
);
|
||||
|
||||
describeChromeOnly('headful tests', function () {
|
||||
describe('headful tests', function () {
|
||||
/* These tests fire up an actual browser so let's
|
||||
* allow a higher timeout
|
||||
*/
|
||||
@ -214,9 +211,7 @@ describeChromeOnly('headful tests', function () {
|
||||
expect(pages).toEqual(['about:blank']);
|
||||
await browser.close();
|
||||
});
|
||||
itFailsWindows(
|
||||
'headless should be able to read cookies written by headful',
|
||||
async () => {
|
||||
it('headless should be able to read cookies written by headful', async () => {
|
||||
/* Needs investigation into why but this fails consistently on Windows CI. */
|
||||
const {server, puppeteer} = getTestState();
|
||||
|
||||
@ -247,8 +242,7 @@ describeChromeOnly('headful tests', function () {
|
||||
// This might throw. See https://github.com/puppeteer/puppeteer/issues/2778
|
||||
await rmAsync(userDataDir).catch(() => {});
|
||||
expect(cookie).toBe('foo=true');
|
||||
}
|
||||
);
|
||||
});
|
||||
// TODO: Support OOOPIF. @see https://github.com/puppeteer/puppeteer/issues/2548
|
||||
xit('OOPIF: should report google.com frame', async () => {
|
||||
const {server, puppeteer} = getTestState();
|
||||
|
@ -20,10 +20,10 @@ import {
|
||||
getTestState,
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
describeFailsFirefox,
|
||||
} from './mocha-utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describeFailsFirefox('Emulate idle state', () => {
|
||||
describe('Emulate idle state', () => {
|
||||
setupTestBrowserHooks();
|
||||
setupTestPageAndContextHooks();
|
||||
|
||||
|
@ -22,11 +22,8 @@ import {
|
||||
} from '../../lib/cjs/puppeteer/common/Browser.js';
|
||||
import {Page} from '../../lib/cjs/puppeteer/common/Page.js';
|
||||
import {HTTPResponse} from '../../lib/cjs/puppeteer/common/HTTPResponse.js';
|
||||
import {
|
||||
getTestState,
|
||||
describeFailsFirefox,
|
||||
itFailsFirefox,
|
||||
} from './mocha-utils.js';
|
||||
import {getTestState} from './mocha-utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describe('ignoreHTTPSErrors', function () {
|
||||
/* Note that this test creates its own browser rather than use
|
||||
@ -59,7 +56,7 @@ describe('ignoreHTTPSErrors', function () {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
describeFailsFirefox('Response.securityDetails', function () {
|
||||
describe('Response.securityDetails', function () {
|
||||
it('should work', async () => {
|
||||
const {httpsServer} = getTestState();
|
||||
|
||||
@ -119,7 +116,7 @@ describe('ignoreHTTPSErrors', function () {
|
||||
expect(error).toBeUndefined();
|
||||
expect(response.ok()).toBe(true);
|
||||
});
|
||||
itFailsFirefox('should work with request interception', async () => {
|
||||
it('should work with request interception', async () => {
|
||||
const {httpsServer} = getTestState();
|
||||
|
||||
await page.setRequestInterception(true);
|
||||
@ -129,7 +126,7 @@ describe('ignoreHTTPSErrors', function () {
|
||||
const response = (await page.goto(httpsServer.EMPTY_PAGE))!;
|
||||
expect(response.status()).toBe(200);
|
||||
});
|
||||
itFailsFirefox('should work with mixed content', async () => {
|
||||
it('should work with mixed content', async () => {
|
||||
const {server, httpsServer} = getTestState();
|
||||
|
||||
httpsServer.setRoute('/mixedcontent.html', (_req, res) => {
|
||||
|
@ -20,8 +20,8 @@ import {
|
||||
getTestState,
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
describeFailsFirefox,
|
||||
} from './mocha-utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
const FILE_TO_UPLOAD = path.join(__dirname, '/../assets/file-to-upload.txt');
|
||||
|
||||
@ -29,7 +29,7 @@ describe('input tests', function () {
|
||||
setupTestBrowserHooks();
|
||||
setupTestPageAndContextHooks();
|
||||
|
||||
describeFailsFirefox('input', function () {
|
||||
describe('input', function () {
|
||||
it('should upload the file', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -76,7 +76,7 @@ describe('input tests', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Page.waitForFileChooser', function () {
|
||||
describe('Page.waitForFileChooser', function () {
|
||||
it('should work when file input is attached to DOM', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
@ -159,7 +159,7 @@ describe('input tests', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('FileChooser.accept', function () {
|
||||
describe('FileChooser.accept', function () {
|
||||
it('should accept single file', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
@ -325,7 +325,7 @@ describe('input tests', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('FileChooser.cancel', function () {
|
||||
describe('FileChooser.cancel', function () {
|
||||
it('should cancel dialog', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
@ -373,7 +373,7 @@ describe('input tests', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('FileChooser.isMultiple', () => {
|
||||
describe('FileChooser.isMultiple', () => {
|
||||
it('should work for single file pick', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
|
@ -17,11 +17,11 @@
|
||||
import expect from 'expect';
|
||||
import {
|
||||
getTestState,
|
||||
itFailsFirefox,
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
shortWaitForArrayToHaveAtLeastNElements,
|
||||
} from './mocha-utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describe('JSHandle', function () {
|
||||
setupTestBrowserHooks();
|
||||
@ -159,7 +159,7 @@ describe('JSHandle', function () {
|
||||
expect(await bHandle.jsonValue()).toEqual(undefined);
|
||||
});
|
||||
|
||||
itFailsFirefox('should not work with dates', async () => {
|
||||
it('should not work with dates', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
const dateHandle = await page.evaluateHandle(() => {
|
||||
@ -409,7 +409,7 @@ describe('JSHandle', function () {
|
||||
});
|
||||
|
||||
describe('JSHandle.click', function () {
|
||||
itFailsFirefox('should work', async () => {
|
||||
it('should work', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
const clicks: Array<[x: number, y: number]> = [];
|
||||
|
@ -21,9 +21,9 @@ import {
|
||||
getTestState,
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
itFailsFirefox,
|
||||
} from './mocha-utils.js';
|
||||
import {KeyInput} from '../../lib/cjs/puppeteer/common/USKeyboardLayout.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describe('Keyboard', function () {
|
||||
setupTestBrowserHooks();
|
||||
@ -45,7 +45,7 @@ describe('Keyboard', function () {
|
||||
})
|
||||
).toBe(text);
|
||||
});
|
||||
itFailsFirefox('should press the metaKey', async () => {
|
||||
it('should press the metaKey', async () => {
|
||||
const {page, isFirefox} = getTestState();
|
||||
|
||||
await page.evaluate(() => {
|
||||
@ -120,9 +120,7 @@ describe('Keyboard', function () {
|
||||
})
|
||||
).toBe('a');
|
||||
});
|
||||
itFailsFirefox(
|
||||
'ElementHandle.press should support |text| option',
|
||||
async () => {
|
||||
it('ElementHandle.press should support |text| option', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||
@ -133,9 +131,8 @@ describe('Keyboard', function () {
|
||||
return document.querySelector('textarea')!.value;
|
||||
})
|
||||
).toBe('ё');
|
||||
}
|
||||
);
|
||||
itFailsFirefox('should send a character with sendCharacter', async () => {
|
||||
});
|
||||
it('should send a character with sendCharacter', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||
@ -162,7 +159,7 @@ describe('Keyboard', function () {
|
||||
})
|
||||
).toBe('嗨a');
|
||||
});
|
||||
itFailsFirefox('should report shiftKey', async () => {
|
||||
it('should report shiftKey', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/input/keyboard.html');
|
||||
@ -353,7 +350,7 @@ describe('Keyboard', function () {
|
||||
})
|
||||
).toBe('He Wrd!');
|
||||
});
|
||||
itFailsFirefox('should specify repeat property', async () => {
|
||||
it('should specify repeat property', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||
@ -401,7 +398,7 @@ describe('Keyboard', function () {
|
||||
})
|
||||
).toBe(false);
|
||||
});
|
||||
itFailsFirefox('should type all kinds of characters', async () => {
|
||||
it('should type all kinds of characters', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||
@ -410,7 +407,7 @@ describe('Keyboard', function () {
|
||||
await page.keyboard.type(text);
|
||||
expect(await page.evaluate('result')).toBe(text);
|
||||
});
|
||||
itFailsFirefox('should specify location', async () => {
|
||||
it('should specify location', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||
@ -460,7 +457,7 @@ describe('Keyboard', function () {
|
||||
});
|
||||
expect(error && error.message).toBe('Unknown key: "😊"');
|
||||
});
|
||||
itFailsFirefox('should type emoji', async () => {
|
||||
it('should type emoji', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||
@ -471,7 +468,7 @@ describe('Keyboard', function () {
|
||||
})
|
||||
).toBe('👹 Tokyo street Japan 🇯🇵');
|
||||
});
|
||||
itFailsFirefox('should type emoji into an iframe', async () => {
|
||||
it('should type emoji into an iframe', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -489,7 +486,7 @@ describe('Keyboard', function () {
|
||||
})
|
||||
).toBe('👹 Tokyo street Japan 🇯🇵');
|
||||
});
|
||||
itFailsFirefox('should press the meta key', async () => {
|
||||
it('should press the meta key', async () => {
|
||||
const {page, isFirefox} = getTestState();
|
||||
|
||||
await page.evaluate(() => {
|
||||
|
@ -24,14 +24,9 @@ import {TLSSocket} from 'tls';
|
||||
import {promisify} from 'util';
|
||||
import {Page} from '../../lib/cjs/puppeteer/common/Page.js';
|
||||
import {Product} from '../../lib/cjs/puppeteer/common/Product.js';
|
||||
import {
|
||||
getTestState,
|
||||
itChromeOnly,
|
||||
itFailsFirefox,
|
||||
itFirefoxOnly,
|
||||
itOnlyRegularInstall,
|
||||
} from './mocha-utils.js';
|
||||
import {getTestState, itOnlyRegularInstall} from './mocha-utils.js';
|
||||
import utils from './utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
const mkdtempAsync = promisify(fs.mkdtemp);
|
||||
const readFileAsync = promisify(fs.readFile);
|
||||
@ -251,7 +246,7 @@ describe('Launcher specs', function () {
|
||||
// This might throw. See https://github.com/puppeteer/puppeteer/issues/2778
|
||||
await rmAsync(userDataDir).catch(() => {});
|
||||
});
|
||||
itChromeOnly('tmp profile should be cleaned up', async () => {
|
||||
it('tmp profile should be cleaned up', async () => {
|
||||
const {defaultBrowserOptions, puppeteer} = getTestState();
|
||||
|
||||
// Set a custom test tmp dir so that we can validate that
|
||||
@ -280,7 +275,7 @@ describe('Launcher specs', function () {
|
||||
// Restore env var
|
||||
process.env['PUPPETEER_TMP_DIR'] = '';
|
||||
});
|
||||
itFirefoxOnly('userDataDir option restores preferences', async () => {
|
||||
it('userDataDir option restores preferences', async () => {
|
||||
const {defaultBrowserOptions, puppeteer} = getTestState();
|
||||
|
||||
const userDataDir = await mkdtempAsync(TMP_FOLDER);
|
||||
@ -326,7 +321,7 @@ describe('Launcher specs', function () {
|
||||
// This might throw. See https://github.com/puppeteer/puppeteer/issues/2778
|
||||
await rmAsync(userDataDir).catch(() => {});
|
||||
});
|
||||
itChromeOnly('userDataDir argument with non-existent dir', async () => {
|
||||
it('userDataDir argument with non-existent dir', async () => {
|
||||
const {isChrome, puppeteer, defaultBrowserOptions} = getTestState();
|
||||
|
||||
const userDataDir = await mkdtempAsync(TMP_FOLDER);
|
||||
@ -460,9 +455,7 @@ describe('Launcher specs', function () {
|
||||
await page.close();
|
||||
await browser.close();
|
||||
});
|
||||
itChromeOnly(
|
||||
'should filter out ignored default arguments in Chrome',
|
||||
async () => {
|
||||
it('should filter out ignored default arguments in Chrome', async () => {
|
||||
const {defaultBrowserOptions, puppeteer} = getTestState();
|
||||
// Make sure we launch with `--enable-automation` by default.
|
||||
const defaultArgs = puppeteer.defaultArgs();
|
||||
@ -480,11 +473,8 @@ describe('Launcher specs', function () {
|
||||
expect(spawnargs.indexOf(defaultArgs[1]!)).not.toBe(-1);
|
||||
expect(spawnargs.indexOf(defaultArgs[2]!)).toBe(-1);
|
||||
await browser.close();
|
||||
}
|
||||
);
|
||||
itFirefoxOnly(
|
||||
'should filter out ignored default argument in Firefox',
|
||||
async () => {
|
||||
});
|
||||
it('should filter out ignored default argument in Firefox', async () => {
|
||||
const {defaultBrowserOptions, puppeteer} = getTestState();
|
||||
|
||||
const defaultArgs = puppeteer.defaultArgs();
|
||||
@ -501,8 +491,7 @@ describe('Launcher specs', function () {
|
||||
expect(spawnargs.indexOf(defaultArgs[0]!)).toBe(-1);
|
||||
expect(spawnargs.indexOf(defaultArgs[1]!)).not.toBe(-1);
|
||||
await browser.close();
|
||||
}
|
||||
);
|
||||
});
|
||||
it('should have default URL when launching browser', async function () {
|
||||
const {defaultBrowserOptions, puppeteer} = getTestState();
|
||||
const browser = await puppeteer.launch(defaultBrowserOptions);
|
||||
@ -512,9 +501,7 @@ describe('Launcher specs', function () {
|
||||
expect(pages).toEqual(['about:blank']);
|
||||
await browser.close();
|
||||
});
|
||||
itFailsFirefox(
|
||||
'should have custom URL when launching browser',
|
||||
async () => {
|
||||
it('should have custom URL when launching browser', async () => {
|
||||
const {server, puppeteer, defaultBrowserOptions} = getTestState();
|
||||
|
||||
const options = Object.assign({}, defaultBrowserOptions);
|
||||
@ -528,8 +515,7 @@ describe('Launcher specs', function () {
|
||||
}
|
||||
expect(page.url()).toBe(server.EMPTY_PAGE);
|
||||
await browser.close();
|
||||
}
|
||||
);
|
||||
});
|
||||
it('should pass the timeout parameter to browser.waitForTarget', async () => {
|
||||
const {puppeteer, defaultBrowserOptions} = getTestState();
|
||||
const options = Object.assign({}, defaultBrowserOptions, {
|
||||
@ -615,9 +601,7 @@ describe('Launcher specs', function () {
|
||||
});
|
||||
expect(error.message).toContain('either pipe or debugging port');
|
||||
});
|
||||
itChromeOnly(
|
||||
'should launch Chrome properly with --no-startup-window and waitForInitialPage=false',
|
||||
async () => {
|
||||
it('should launch Chrome properly with --no-startup-window and waitForInitialPage=false', async () => {
|
||||
const {defaultBrowserOptions, puppeteer} = getTestState();
|
||||
const options = {
|
||||
waitForInitialPage: false,
|
||||
@ -631,8 +615,7 @@ describe('Launcher specs', function () {
|
||||
const pages = await browser.pages();
|
||||
expect(pages.length).toBe(0);
|
||||
await browser.close();
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Puppeteer.launch', function () {
|
||||
@ -775,7 +758,7 @@ describe('Launcher specs', function () {
|
||||
});
|
||||
|
||||
// @see https://github.com/puppeteer/puppeteer/issues/4197
|
||||
itFailsFirefox('should support targetFilter option', async () => {
|
||||
it('should support targetFilter option', async () => {
|
||||
const {server, puppeteer, defaultBrowserOptions} = getTestState();
|
||||
|
||||
const originalBrowser = await puppeteer.launch(defaultBrowserOptions);
|
||||
@ -809,9 +792,7 @@ describe('Launcher specs', function () {
|
||||
.sort()
|
||||
).toEqual(['about:blank', server.EMPTY_PAGE]);
|
||||
});
|
||||
itFailsFirefox(
|
||||
'should be able to reconnect to a disconnected browser',
|
||||
async () => {
|
||||
it('should be able to reconnect to a disconnected browser', async () => {
|
||||
const {server, puppeteer, defaultBrowserOptions} = getTestState();
|
||||
|
||||
const originalBrowser = await puppeteer.launch(defaultBrowserOptions);
|
||||
@ -838,12 +819,9 @@ describe('Launcher specs', function () {
|
||||
})
|
||||
).toBe(56);
|
||||
await browser.close();
|
||||
}
|
||||
);
|
||||
});
|
||||
// @see https://github.com/puppeteer/puppeteer/issues/4197#issuecomment-481793410
|
||||
itFailsFirefox(
|
||||
'should be able to connect to the same page simultaneously',
|
||||
async () => {
|
||||
it('should be able to connect to the same page simultaneously', async () => {
|
||||
const {puppeteer, defaultBrowserOptions} = getTestState();
|
||||
|
||||
const browserOne = await puppeteer.launch(defaultBrowserOptions);
|
||||
@ -869,8 +847,7 @@ describe('Launcher specs', function () {
|
||||
})
|
||||
).toBe(42);
|
||||
await browserOne.close();
|
||||
}
|
||||
);
|
||||
});
|
||||
it('should be able to reconnect', async () => {
|
||||
const {puppeteer, server, defaultBrowserOptions} = getTestState();
|
||||
const browserOne = await puppeteer.launch(defaultBrowserOptions);
|
||||
@ -933,7 +910,7 @@ describe('Launcher specs', function () {
|
||||
|
||||
describe('when the product is chrome, platform is not darwin, and arch is arm64', () => {
|
||||
describe('and the executable exists', () => {
|
||||
itChromeOnly('returns /usr/bin/chromium-browser', async () => {
|
||||
it('returns /usr/bin/chromium-browser', async () => {
|
||||
const {puppeteer} = getTestState();
|
||||
const osPlatformStub = sinon.stub(os, 'platform').returns('linux');
|
||||
const osArchStub = sinon.stub(os, 'arch').returns('arm64');
|
||||
@ -972,13 +949,9 @@ describe('Launcher specs', function () {
|
||||
});
|
||||
});
|
||||
describe('and the executable does not exist', () => {
|
||||
itChromeOnly(
|
||||
'does not return /usr/bin/chromium-browser',
|
||||
async () => {
|
||||
it('does not return /usr/bin/chromium-browser', async () => {
|
||||
const {puppeteer} = getTestState();
|
||||
const osPlatformStub = sinon
|
||||
.stub(os, 'platform')
|
||||
.returns('linux');
|
||||
const osPlatformStub = sinon.stub(os, 'platform').returns('linux');
|
||||
const osArchStub = sinon.stub(os, 'arch').returns('arm64');
|
||||
const fsExistsStub = sinon.stub(fs, 'existsSync');
|
||||
fsExistsStub.withArgs('/usr/bin/chromium-browser').returns(false);
|
||||
@ -990,15 +963,14 @@ describe('Launcher specs', function () {
|
||||
osPlatformStub.restore();
|
||||
osArchStub.restore();
|
||||
fsExistsStub.restore();
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Browser target events', function () {
|
||||
itFailsFirefox('should work', async () => {
|
||||
it('should work', async () => {
|
||||
const {server, puppeteer, defaultBrowserOptions} = getTestState();
|
||||
|
||||
const browser = await puppeteer.launch(defaultBrowserOptions);
|
||||
@ -1021,9 +993,7 @@ describe('Launcher specs', function () {
|
||||
});
|
||||
|
||||
describe('Browser.Events.disconnected', function () {
|
||||
itFailsFirefox(
|
||||
'should be emitted when: browser gets closed, disconnected or underlying websocket gets closed',
|
||||
async () => {
|
||||
it('should be emitted when: browser gets closed, disconnected or underlying websocket gets closed', async () => {
|
||||
const {puppeteer, defaultBrowserOptions} = getTestState();
|
||||
const originalBrowser = await puppeteer.launch(defaultBrowserOptions);
|
||||
const browserWSEndpoint = originalBrowser.wsEndpoint();
|
||||
@ -1065,7 +1035,6 @@ describe('Launcher specs', function () {
|
||||
expect(disconnectedOriginal).toBe(1);
|
||||
expect(disconnectedRemote1).toBe(1);
|
||||
expect(disconnectedRemote2).toBe(1);
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -17,7 +17,6 @@
|
||||
import Protocol from 'devtools-protocol';
|
||||
import expect from 'expect';
|
||||
import * as fs from 'fs';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import rimraf from 'rimraf';
|
||||
import sinon from 'sinon';
|
||||
@ -34,6 +33,8 @@ import {
|
||||
import puppeteer from '../../lib/cjs/puppeteer/puppeteer.js';
|
||||
import {TestServer} from '../../utils/testserver/lib/index.js';
|
||||
import {extendExpectWithToBeGolden} from './utils.js';
|
||||
import * as Mocha from 'mocha';
|
||||
import {getTestId} from '../../utils/mochaRunner/lib/utils.js';
|
||||
|
||||
const setupServer = async () => {
|
||||
const assetsPath = path.join(__dirname, '../assets');
|
||||
@ -63,14 +64,14 @@ export const getTestState = (): PuppeteerTestState => {
|
||||
};
|
||||
|
||||
const product =
|
||||
process.env['PRODUCT'] || process.env['PUPPETEER_PRODUCT'] || 'Chromium';
|
||||
process.env['PRODUCT'] || process.env['PUPPETEER_PRODUCT'] || 'chrome';
|
||||
|
||||
const alternativeInstall = process.env['PUPPETEER_ALT_INSTALL'] || false;
|
||||
|
||||
const headless = (process.env['HEADLESS'] || 'true').trim().toLowerCase();
|
||||
const isHeadless = headless === 'true' || headless === 'chrome';
|
||||
const isFirefox = product === 'firefox';
|
||||
const isChrome = product === 'Chromium';
|
||||
const isChrome = product === 'chrome';
|
||||
|
||||
let extraLaunchOptions = {};
|
||||
try {
|
||||
@ -125,7 +126,11 @@ declare module 'expect/build/types' {
|
||||
}
|
||||
|
||||
const setupGoldenAssertions = (): void => {
|
||||
const suffix = product.toLowerCase();
|
||||
let suffix = product.toLowerCase();
|
||||
if (suffix === 'chrome') {
|
||||
// TODO: to avoid moving golden folders.
|
||||
suffix = 'chromium';
|
||||
}
|
||||
const GOLDEN_DIR = path.join(__dirname, `../golden-${suffix}`);
|
||||
const OUTPUT_DIR = path.join(__dirname, `../output-${suffix}`);
|
||||
if (fs.existsSync(OUTPUT_DIR)) {
|
||||
@ -152,64 +157,9 @@ interface PuppeteerTestState {
|
||||
}
|
||||
const state: Partial<PuppeteerTestState> = {};
|
||||
|
||||
export const itFailsFirefox = (
|
||||
description: string,
|
||||
body: Mocha.Func
|
||||
): Mocha.Test => {
|
||||
if (isFirefox) {
|
||||
return xit(description, body);
|
||||
} else {
|
||||
return it(description, body);
|
||||
}
|
||||
};
|
||||
|
||||
export const itChromeOnly = (
|
||||
description: string,
|
||||
body: Mocha.Func
|
||||
): Mocha.Test => {
|
||||
if (isChrome) {
|
||||
return it(description, body);
|
||||
} else {
|
||||
return xit(description, body);
|
||||
}
|
||||
};
|
||||
|
||||
export const itHeadlessOnly = (
|
||||
description: string,
|
||||
body: Mocha.Func
|
||||
): Mocha.Test => {
|
||||
if (isChrome && isHeadless === true) {
|
||||
return it(description, body);
|
||||
} else {
|
||||
return xit(description, body);
|
||||
}
|
||||
};
|
||||
|
||||
export const itHeadfulOnly = (
|
||||
description: string,
|
||||
body: Mocha.Func
|
||||
): Mocha.Test => {
|
||||
if (isChrome && isHeadless === false) {
|
||||
return it(description, body);
|
||||
} else {
|
||||
return xit(description, body);
|
||||
}
|
||||
};
|
||||
|
||||
export const itFirefoxOnly = (
|
||||
description: string,
|
||||
body: Mocha.Func
|
||||
): Mocha.Test => {
|
||||
if (isFirefox) {
|
||||
return it(description, body);
|
||||
} else {
|
||||
return xit(description, body);
|
||||
}
|
||||
};
|
||||
|
||||
export const itOnlyRegularInstall = (
|
||||
description: string,
|
||||
body: Mocha.Func
|
||||
body: Mocha.AsyncFunc
|
||||
): Mocha.Test => {
|
||||
if (alternativeInstall || process.env['BINARY']) {
|
||||
return xit(description, body);
|
||||
@ -218,50 +168,10 @@ export const itOnlyRegularInstall = (
|
||||
}
|
||||
};
|
||||
|
||||
export const itFailsWindowsUntilDate = (
|
||||
date: Date,
|
||||
description: string,
|
||||
body: Mocha.Func
|
||||
): Mocha.Test => {
|
||||
if (os.platform() === 'win32' && Date.now() < date.getTime()) {
|
||||
// we are within the deferred time so skip the test
|
||||
return xit(description, body);
|
||||
}
|
||||
|
||||
return it(description, body);
|
||||
};
|
||||
|
||||
export const itFailsWindows = (
|
||||
description: string,
|
||||
body: Mocha.Func
|
||||
): Mocha.Test => {
|
||||
if (os.platform() === 'win32') {
|
||||
return xit(description, body);
|
||||
}
|
||||
return it(description, body);
|
||||
};
|
||||
|
||||
export const describeFailsFirefox = (
|
||||
description: string,
|
||||
body: (this: Mocha.Suite) => void
|
||||
): void | Mocha.Suite => {
|
||||
if (isFirefox) {
|
||||
return xdescribe(description, body);
|
||||
} else {
|
||||
return describe(description, body);
|
||||
}
|
||||
};
|
||||
|
||||
export const describeChromeOnly = (
|
||||
description: string,
|
||||
body: (this: Mocha.Suite) => void
|
||||
): Mocha.Suite | void => {
|
||||
if (isChrome) {
|
||||
return describe(description, body);
|
||||
}
|
||||
};
|
||||
|
||||
if (process.env['MOCHA_WORKER_ID'] === '0') {
|
||||
if (
|
||||
process.env['MOCHA_WORKER_ID'] === undefined ||
|
||||
process.env['MOCHA_WORKER_ID'] === '0'
|
||||
) {
|
||||
console.log(
|
||||
`Running unit tests with:
|
||||
-> product: ${product}
|
||||
@ -290,7 +200,7 @@ export const setupTestBrowserHooks = (): void => {
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await state.browser!.close();
|
||||
await state.browser?.close();
|
||||
state.browser = undefined;
|
||||
});
|
||||
};
|
||||
@ -302,7 +212,7 @@ export const setupTestPageAndContextHooks = (): void => {
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await state.context!.close();
|
||||
await state.context?.close();
|
||||
state.context = undefined;
|
||||
state.page = undefined;
|
||||
});
|
||||
@ -387,3 +297,34 @@ export const shortWaitForArrayToHaveAtLeastNElements = async (
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
type SyncFn = (this: Mocha.Context) => void;
|
||||
|
||||
const skippedTests: string[] = process.env['PUPPETEER_SKIPPED_TEST_CONFIG']
|
||||
? JSON.parse(process.env['PUPPETEER_SKIPPED_TEST_CONFIG'])
|
||||
: [];
|
||||
|
||||
function skipTestIfNeeded(test: Mocha.Test): void {
|
||||
const testId = getTestId(test.file!, test.fullTitle());
|
||||
if (
|
||||
skippedTests.find(skippedTest => {
|
||||
return testId.startsWith(skippedTest);
|
||||
})
|
||||
) {
|
||||
try {
|
||||
test.skip();
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
|
||||
export function it(title: string, fn?: Mocha.AsyncFunc | SyncFn): Mocha.Test {
|
||||
const test = Mocha.it.call(null, title, fn as any);
|
||||
skipTestIfNeeded(test);
|
||||
return test;
|
||||
}
|
||||
|
||||
it.only = function (title: string, fn?: Mocha.AsyncFunc | SyncFn): Mocha.Test {
|
||||
const test = Mocha.it.only.call(null, title, fn as any);
|
||||
skipTestIfNeeded(test);
|
||||
return test;
|
||||
};
|
||||
|
@ -19,9 +19,9 @@ import {
|
||||
getTestState,
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
itFailsFirefox,
|
||||
} from './mocha-utils.js';
|
||||
import {KeyInput} from '../../lib/cjs/puppeteer/common/USKeyboardLayout.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
interface Dimensions {
|
||||
x: number;
|
||||
@ -115,7 +115,7 @@ describe('Mouse', function () {
|
||||
})
|
||||
).toBe(text);
|
||||
});
|
||||
itFailsFirefox('should trigger hover state', async () => {
|
||||
it('should trigger hover state', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/input/scrollable.html');
|
||||
@ -138,9 +138,7 @@ describe('Mouse', function () {
|
||||
})
|
||||
).toBe('button-91');
|
||||
});
|
||||
itFailsFirefox(
|
||||
'should trigger hover state with removed window.Node',
|
||||
async () => {
|
||||
it('should trigger hover state with removed window.Node', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/input/scrollable.html');
|
||||
@ -154,8 +152,7 @@ describe('Mouse', function () {
|
||||
return document.querySelector('button:hover')!.id;
|
||||
})
|
||||
).toBe('button-6');
|
||||
}
|
||||
);
|
||||
});
|
||||
it('should set modifier keys on click', async () => {
|
||||
const {page, server, isFirefox} = getTestState();
|
||||
|
||||
@ -202,7 +199,7 @@ describe('Mouse', function () {
|
||||
}
|
||||
}
|
||||
});
|
||||
itFailsFirefox('should send mouse wheel events', async () => {
|
||||
it('should send mouse wheel events', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/input/wheel.html');
|
||||
@ -225,7 +222,7 @@ describe('Mouse', function () {
|
||||
height: 230,
|
||||
});
|
||||
});
|
||||
itFailsFirefox('should tween mouse movement', async () => {
|
||||
it('should tween mouse movement', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
await page.mouse.move(100, 100);
|
||||
|
@ -20,12 +20,11 @@ import {
|
||||
getTestState,
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
itFailsFirefox,
|
||||
describeFailsFirefox,
|
||||
} from './mocha-utils.js';
|
||||
import os from 'os';
|
||||
import {ServerResponse} from 'http';
|
||||
import {HTTPRequest} from '../../lib/cjs/puppeteer/common/HTTPRequest.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describe('navigation', function () {
|
||||
setupTestBrowserHooks();
|
||||
@ -67,7 +66,7 @@ describe('navigation', function () {
|
||||
const response = (await page.goto(server.PREFIX + '/historyapi.html'))!;
|
||||
expect(response.status()).toBe(200);
|
||||
});
|
||||
itFailsFirefox('should work with subframes return 204', async () => {
|
||||
it('should work with subframes return 204', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
server.setRoute('/frames/frame.html', (_req, res) => {
|
||||
@ -82,7 +81,7 @@ describe('navigation', function () {
|
||||
});
|
||||
expect(error).toBeUndefined();
|
||||
});
|
||||
itFailsFirefox('should fail when server returns 204', async () => {
|
||||
it('should fail when server returns 204', async () => {
|
||||
const {page, server, isChrome} = getTestState();
|
||||
|
||||
server.setRoute('/empty.html', (_req, res) => {
|
||||
@ -124,29 +123,23 @@ describe('navigation', function () {
|
||||
const response = await page.goto(server.PREFIX + '/grid.html');
|
||||
expect(response!.status()).toBe(200);
|
||||
});
|
||||
itFailsFirefox(
|
||||
'should navigate to empty page with networkidle0',
|
||||
async () => {
|
||||
it('should navigate to empty page with networkidle0', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
const response = await page.goto(server.EMPTY_PAGE, {
|
||||
waitUntil: 'networkidle0',
|
||||
});
|
||||
expect(response!.status()).toBe(200);
|
||||
}
|
||||
);
|
||||
itFailsFirefox(
|
||||
'should navigate to empty page with networkidle2',
|
||||
async () => {
|
||||
});
|
||||
it('should navigate to empty page with networkidle2', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
const response = await page.goto(server.EMPTY_PAGE, {
|
||||
waitUntil: 'networkidle2',
|
||||
});
|
||||
expect(response!.status()).toBe(200);
|
||||
}
|
||||
);
|
||||
itFailsFirefox('should fail when navigating to bad url', async () => {
|
||||
});
|
||||
it('should fail when navigating to bad url', async () => {
|
||||
const {page, isChrome} = getTestState();
|
||||
|
||||
let error!: Error;
|
||||
@ -175,7 +168,7 @@ describe('navigation', function () {
|
||||
: 'net::ERR_CERT_AUTHORITY_INVALID';
|
||||
}
|
||||
|
||||
itFailsFirefox('should fail when navigating to bad SSL', async () => {
|
||||
it('should fail when navigating to bad SSL', async () => {
|
||||
const {page, httpsServer, isChrome} = getTestState();
|
||||
|
||||
// Make sure that network events do not emit 'undefined'.
|
||||
@ -311,7 +304,7 @@ describe('navigation', function () {
|
||||
const response = (await page.goto(server.EMPTY_PAGE))!;
|
||||
expect(response.ok()).toBe(true);
|
||||
});
|
||||
itFailsFirefox('should work when navigating to data url', async () => {
|
||||
it('should work when navigating to data url', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
const response = (await page.goto('data:text/html,hello'))!;
|
||||
@ -334,9 +327,7 @@ describe('navigation', function () {
|
||||
expect(response.ok()).toBe(true);
|
||||
expect(response.url()).toBe(server.EMPTY_PAGE);
|
||||
});
|
||||
itFailsFirefox(
|
||||
'should wait for network idle to succeed navigation',
|
||||
async () => {
|
||||
it('should wait for network idle to succeed navigation', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
let responses: ServerResponse[] = [];
|
||||
@ -364,12 +355,9 @@ describe('navigation', function () {
|
||||
|
||||
// Navigate to a page which loads immediately and then does a bunch of
|
||||
// requests via javascript's fetch method.
|
||||
const navigationPromise = page.goto(
|
||||
server.PREFIX + '/networkidle.html',
|
||||
{
|
||||
const navigationPromise = page.goto(server.PREFIX + '/networkidle.html', {
|
||||
waitUntil: 'networkidle0',
|
||||
}
|
||||
);
|
||||
});
|
||||
// Track when the navigation gets completed.
|
||||
let navigationFinished = false;
|
||||
navigationPromise.then(() => {
|
||||
@ -411,8 +399,7 @@ describe('navigation', function () {
|
||||
const response = (await navigationPromise)!;
|
||||
// Expect navigation to succeed.
|
||||
expect(response.ok()).toBe(true);
|
||||
}
|
||||
);
|
||||
});
|
||||
it('should not leak listeners during navigation', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -461,9 +448,7 @@ describe('navigation', function () {
|
||||
process.removeListener('warning', warningHandler);
|
||||
expect(warning).toBe(null);
|
||||
});
|
||||
itFailsFirefox(
|
||||
'should navigate to dataURL and fire dataURL requests',
|
||||
async () => {
|
||||
it('should navigate to dataURL and fire dataURL requests', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
const requests: HTTPRequest[] = [];
|
||||
@ -475,11 +460,8 @@ describe('navigation', function () {
|
||||
expect(response.status()).toBe(200);
|
||||
expect(requests.length).toBe(1);
|
||||
expect(requests[0]!.url()).toBe(dataURL);
|
||||
}
|
||||
);
|
||||
itFailsFirefox(
|
||||
'should navigate to URL with hash and fire requests without hash',
|
||||
async () => {
|
||||
});
|
||||
it('should navigate to URL with hash and fire requests without hash', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
const requests: HTTPRequest[] = [];
|
||||
@ -491,8 +473,7 @@ describe('navigation', function () {
|
||||
expect(response.url()).toBe(server.EMPTY_PAGE);
|
||||
expect(requests.length).toBe(1);
|
||||
expect(requests[0]!.url()).toBe(server.EMPTY_PAGE);
|
||||
}
|
||||
);
|
||||
});
|
||||
it('should work with self requesting page', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -512,7 +493,7 @@ describe('navigation', function () {
|
||||
}
|
||||
expect(error.message).toContain(url);
|
||||
});
|
||||
itFailsFirefox('should send referer', async () => {
|
||||
it('should send referer', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
const [request1, request2] = await Promise.all([
|
||||
@ -582,7 +563,7 @@ describe('navigation', function () {
|
||||
expect(response).toBe(null);
|
||||
expect(page.url()).toBe(server.EMPTY_PAGE + '#foobar');
|
||||
});
|
||||
itFailsFirefox('should work with history.pushState()', async () => {
|
||||
it('should work with history.pushState()', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -599,7 +580,7 @@ describe('navigation', function () {
|
||||
expect(response).toBe(null);
|
||||
expect(page.url()).toBe(server.PREFIX + '/wow.html');
|
||||
});
|
||||
itFailsFirefox('should work with history.replaceState()', async () => {
|
||||
it('should work with history.replaceState()', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -616,9 +597,7 @@ describe('navigation', function () {
|
||||
expect(response).toBe(null);
|
||||
expect(page.url()).toBe(server.PREFIX + '/replaced.html');
|
||||
});
|
||||
itFailsFirefox(
|
||||
'should work with DOM history.back()/history.forward()',
|
||||
async () => {
|
||||
it('should work with DOM history.back()/history.forward()', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -645,11 +624,8 @@ describe('navigation', function () {
|
||||
]);
|
||||
expect(forwardResponse).toBe(null);
|
||||
expect(page.url()).toBe(server.PREFIX + '/second.html');
|
||||
}
|
||||
);
|
||||
itFailsFirefox(
|
||||
'should work when subframe issues window.stop()',
|
||||
async () => {
|
||||
});
|
||||
it('should work when subframe issues window.stop()', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
server.setRoute('/frames/style.css', () => {});
|
||||
@ -670,8 +646,7 @@ describe('navigation', function () {
|
||||
}),
|
||||
navigationPromise,
|
||||
]);
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Page.goBack', function () {
|
||||
@ -692,7 +667,7 @@ describe('navigation', function () {
|
||||
response = (await page.goForward())!;
|
||||
expect(response).toBe(null);
|
||||
});
|
||||
itFailsFirefox('should work with HistoryAPI', async () => {
|
||||
it('should work with HistoryAPI', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -711,7 +686,7 @@ describe('navigation', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Frame.goto', function () {
|
||||
describe('Frame.goto', function () {
|
||||
it('should navigate subframes', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -776,7 +751,7 @@ describe('navigation', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Frame.waitForNavigation', function () {
|
||||
describe('Frame.waitForNavigation', function () {
|
||||
it('should work', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
|
@ -22,14 +22,11 @@ import {
|
||||
getTestState,
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
itFailsFirefox,
|
||||
describeFailsFirefox,
|
||||
itChromeOnly,
|
||||
itFirefoxOnly,
|
||||
} from './mocha-utils.js';
|
||||
import {HTTPRequest} from '../../lib/cjs/puppeteer/common/HTTPRequest.js';
|
||||
import {HTTPResponse} from '../../lib/cjs/puppeteer/common/HTTPResponse.js';
|
||||
import {ServerResponse} from 'http';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describe('network', function () {
|
||||
setupTestBrowserHooks();
|
||||
@ -83,7 +80,7 @@ describe('network', function () {
|
||||
expect(requests.length).toBe(1);
|
||||
expect(requests[0]!.frame()).toBe(page.mainFrame());
|
||||
});
|
||||
itFailsFirefox('should work for subframe navigation request', async () => {
|
||||
it('should work for subframe navigation request', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
(await page.goto(server.EMPTY_PAGE))!;
|
||||
@ -115,13 +112,13 @@ describe('network', function () {
|
||||
});
|
||||
|
||||
describe('Request.headers', function () {
|
||||
itChromeOnly('should define Chrome as user agent header', async () => {
|
||||
it('should define Chrome as user agent header', async () => {
|
||||
const {page, server} = getTestState();
|
||||
const response = (await page.goto(server.EMPTY_PAGE))!;
|
||||
expect(response.request().headers()['user-agent']).toContain('Chrome');
|
||||
});
|
||||
|
||||
itFirefoxOnly('should define Firefox as user agent header', async () => {
|
||||
it('should define Firefox as user agent header', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
const response = (await page.goto(server.EMPTY_PAGE))!;
|
||||
@ -142,7 +139,7 @@ describe('network', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Request.initiator', () => {
|
||||
describe('Request.initiator', () => {
|
||||
it('should return the initiator', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -187,7 +184,7 @@ describe('network', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Response.fromCache', function () {
|
||||
describe('Response.fromCache', function () {
|
||||
it('should return |false| for non-cached content', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -218,7 +215,7 @@ describe('network', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Response.fromServiceWorker', function () {
|
||||
describe('Response.fromServiceWorker', function () {
|
||||
it('should return |false| for non-service-worker content', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -253,7 +250,7 @@ describe('network', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Request.postData', function () {
|
||||
describe('Request.postData', function () {
|
||||
it('should work', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -284,7 +281,7 @@ describe('network', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Response.text', function () {
|
||||
describe('Response.text', function () {
|
||||
it('should work', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -367,7 +364,7 @@ describe('network', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Response.json', function () {
|
||||
describe('Response.json', function () {
|
||||
it('should work', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -376,7 +373,7 @@ describe('network', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Response.buffer', function () {
|
||||
describe('Response.buffer', function () {
|
||||
it('should work', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -461,7 +458,7 @@ describe('network', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Response.timing', function () {
|
||||
describe('Response.timing', function () {
|
||||
it('returns timing information', async () => {
|
||||
const {page, server} = getTestState();
|
||||
const responses: HTTPResponse[] = [];
|
||||
@ -474,7 +471,7 @@ describe('network', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Network Events', function () {
|
||||
describe('Network Events', function () {
|
||||
it('Page.Events.Request', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -624,7 +621,7 @@ describe('network', function () {
|
||||
});
|
||||
|
||||
describe('Request.isNavigationRequest', () => {
|
||||
itFailsFirefox('should work', async () => {
|
||||
it('should work', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
const requests = new Map();
|
||||
@ -639,7 +636,7 @@ describe('network', function () {
|
||||
expect(requests.get('script.js').isNavigationRequest()).toBe(false);
|
||||
expect(requests.get('style.css').isNavigationRequest()).toBe(false);
|
||||
});
|
||||
itFailsFirefox('should work with request interception', async () => {
|
||||
it('should work with request interception', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
const requests = new Map();
|
||||
@ -656,7 +653,7 @@ describe('network', function () {
|
||||
expect(requests.get('script.js').isNavigationRequest()).toBe(false);
|
||||
expect(requests.get('style.css').isNavigationRequest()).toBe(false);
|
||||
});
|
||||
itFailsFirefox('should work when navigating to image', async () => {
|
||||
it('should work when navigating to image', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
const requests: HTTPRequest[] = [];
|
||||
@ -668,7 +665,7 @@ describe('network', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Page.setExtraHTTPHeaders', function () {
|
||||
describe('Page.setExtraHTTPHeaders', function () {
|
||||
it('should work', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -697,7 +694,7 @@ describe('network', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Page.authenticate', function () {
|
||||
describe('Page.authenticate', function () {
|
||||
it('should work', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -794,7 +791,7 @@ describe('network', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('raw network headers', async () => {
|
||||
describe('raw network headers', async () => {
|
||||
it('Same-origin set-cookie navigation', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
|
@ -16,18 +16,15 @@
|
||||
|
||||
import utils from './utils.js';
|
||||
import expect from 'expect';
|
||||
import {
|
||||
getTestState,
|
||||
describeChromeOnly,
|
||||
itFailsFirefox,
|
||||
} from './mocha-utils.js';
|
||||
import {getTestState} from './mocha-utils.js';
|
||||
import {
|
||||
Browser,
|
||||
BrowserContext,
|
||||
} from '../../lib/cjs/puppeteer/common/Browser.js';
|
||||
import {Page} from '../../lib/cjs/puppeteer/common/Page.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describeChromeOnly('OOPIF', function () {
|
||||
describe('OOPIF', function () {
|
||||
/* We use a special browser for this test as we need the --site-per-process flag */
|
||||
let browser: Browser;
|
||||
let context: BrowserContext;
|
||||
@ -207,6 +204,7 @@ describeChromeOnly('OOPIF', function () {
|
||||
await utils.navigateFrame(page, 'frame1', server.EMPTY_PAGE);
|
||||
expect(frame.url()).toBe(server.EMPTY_PAGE);
|
||||
});
|
||||
|
||||
it('should support evaluating in oop iframes', async () => {
|
||||
const {server} = getTestState();
|
||||
|
||||
@ -420,7 +418,7 @@ describeChromeOnly('OOPIF', function () {
|
||||
browser1.disconnect();
|
||||
});
|
||||
|
||||
itFailsFirefox('should support lazy OOP frames', async () => {
|
||||
it('should support lazy OOP frames', async () => {
|
||||
const {server} = getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/lazy-oopif-frame.html');
|
||||
|
@ -22,13 +22,12 @@ import {CDPSession} from '../../lib/cjs/puppeteer/common/Connection.js';
|
||||
import {ConsoleMessage} from '../../lib/cjs/puppeteer/common/ConsoleMessage.js';
|
||||
import {Metrics, Page} from '../../lib/cjs/puppeteer/common/Page.js';
|
||||
import {
|
||||
describeFailsFirefox,
|
||||
getTestState,
|
||||
itFailsFirefox,
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
} from './mocha-utils.js';
|
||||
import utils, {attachFrame, waitEvent} from './utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describe('Page', function () {
|
||||
setupTestBrowserHooks();
|
||||
@ -59,7 +58,7 @@ describe('Page', function () {
|
||||
await newPage.close();
|
||||
expect(await browser.pages()).not.toContain(newPage);
|
||||
});
|
||||
itFailsFirefox('should run beforeunload if asked for', async () => {
|
||||
it('should run beforeunload if asked for', async () => {
|
||||
const {context, server, isChrome} = getTestState();
|
||||
|
||||
const newPage = await context.newPage();
|
||||
@ -79,7 +78,7 @@ describe('Page', function () {
|
||||
await dialog.accept();
|
||||
await pageClosingPromise;
|
||||
});
|
||||
itFailsFirefox('should *not* run beforeunload by default', async () => {
|
||||
it('should *not* run beforeunload by default', async () => {
|
||||
const {context, server} = getTestState();
|
||||
|
||||
const newPage = await context.newPage();
|
||||
@ -97,7 +96,7 @@ describe('Page', function () {
|
||||
await newPage.close();
|
||||
expect(newPage.isClosed()).toBe(true);
|
||||
});
|
||||
itFailsFirefox('should terminate network waiters', async () => {
|
||||
it('should terminate network waiters', async () => {
|
||||
const {context, server} = getTestState();
|
||||
|
||||
const newPage = await context.newPage();
|
||||
@ -182,7 +181,7 @@ describe('Page', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Page.Events.error', function () {
|
||||
describe('Page.Events.error', function () {
|
||||
it('should throw when page crashes', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
@ -196,7 +195,7 @@ describe('Page', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Page.Events.Popup', function () {
|
||||
describe('Page.Events.Popup', function () {
|
||||
it('should work', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
@ -354,7 +353,7 @@ describe('Page', function () {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
expect(await getPermission(page, 'geolocation')).toBe('prompt');
|
||||
});
|
||||
itFailsFirefox('should deny permission when not listed', async () => {
|
||||
it('should deny permission when not listed', async () => {
|
||||
const {page, server, context} = getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -374,14 +373,14 @@ describe('Page', function () {
|
||||
});
|
||||
expect(error.message).toBe('Unknown permission: foo');
|
||||
});
|
||||
itFailsFirefox('should grant permission when listed', async () => {
|
||||
it('should grant permission when listed', async () => {
|
||||
const {page, server, context} = getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await context.overridePermissions(server.EMPTY_PAGE, ['geolocation']);
|
||||
expect(await getPermission(page, 'geolocation')).toBe('granted');
|
||||
});
|
||||
itFailsFirefox('should reset permissions', async () => {
|
||||
it('should reset permissions', async () => {
|
||||
const {page, server, context} = getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -390,7 +389,7 @@ describe('Page', function () {
|
||||
await context.clearPermissionOverrides();
|
||||
expect(await getPermission(page, 'geolocation')).toBe('prompt');
|
||||
});
|
||||
itFailsFirefox('should trigger permission onchange', async () => {
|
||||
it('should trigger permission onchange', async () => {
|
||||
const {page, server, context, isHeadless} = getTestState();
|
||||
|
||||
// TODO: re-enable this test in headful once crbug.com/1324480 rolls out.
|
||||
@ -434,9 +433,7 @@ describe('Page', function () {
|
||||
})
|
||||
).toEqual(['prompt', 'denied', 'granted', 'prompt']);
|
||||
});
|
||||
itFailsFirefox(
|
||||
'should isolate permissions between browser contexts',
|
||||
async () => {
|
||||
it('should isolate permissions between browser contexts', async () => {
|
||||
const {page, server, context, browser} = getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -458,9 +455,8 @@ describe('Page', function () {
|
||||
expect(await getPermission(otherPage, 'geolocation')).toBe('granted');
|
||||
|
||||
await otherContext.close();
|
||||
}
|
||||
);
|
||||
itFailsFirefox('should grant persistent-storage', async () => {
|
||||
});
|
||||
it('should grant persistent-storage', async () => {
|
||||
const {page, server, context} = getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -475,7 +471,7 @@ describe('Page', function () {
|
||||
});
|
||||
|
||||
describe('Page.setGeolocation', function () {
|
||||
itFailsFirefox('should work', async () => {
|
||||
it('should work', async () => {
|
||||
const {page, server, context} = getTestState();
|
||||
|
||||
await context.overridePermissions(server.PREFIX, ['geolocation']);
|
||||
@ -509,7 +505,7 @@ describe('Page', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Page.setOfflineMode', function () {
|
||||
describe('Page.setOfflineMode', function () {
|
||||
it('should work', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -547,7 +543,7 @@ describe('Page', function () {
|
||||
});
|
||||
|
||||
describe('ExecutionContext.queryObjects', function () {
|
||||
itFailsFirefox('should work', async () => {
|
||||
it('should work', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
// Instantiate an object
|
||||
@ -567,7 +563,7 @@ describe('Page', function () {
|
||||
}, objectsHandle);
|
||||
expect(values).toEqual(['hello', 'world']);
|
||||
});
|
||||
itFailsFirefox('should work for non-blank page', async () => {
|
||||
it('should work for non-blank page', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
// Instantiate an object
|
||||
@ -613,7 +609,7 @@ describe('Page', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Page.Events.Console', function () {
|
||||
describe('Page.Events.Console', function () {
|
||||
it('should work', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
@ -802,7 +798,7 @@ describe('Page', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Page.metrics', function () {
|
||||
describe('Page.metrics', function () {
|
||||
it('should get metrics from a page', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
@ -1108,7 +1104,7 @@ describe('Page', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Page.exposeFunction', function () {
|
||||
describe('Page.exposeFunction', function () {
|
||||
it('should work', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
@ -1266,7 +1262,7 @@ describe('Page', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Page.Events.PageError', function () {
|
||||
describe('Page.Events.PageError', function () {
|
||||
it('should fire', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -1329,7 +1325,7 @@ describe('Page', function () {
|
||||
})
|
||||
).toContain('iPhone');
|
||||
});
|
||||
itFailsFirefox('should work with additional userAgentMetdata', async () => {
|
||||
it('should work with additional userAgentMetdata', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.setUserAgent('MockBrowser', {
|
||||
@ -1496,7 +1492,7 @@ describe('Page', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Page.setBypassCSP', function () {
|
||||
describe('Page.setBypassCSP', function () {
|
||||
it('should bypass CSP meta tag', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -1879,9 +1875,7 @@ describe('Page', function () {
|
||||
).toBe('rgb(0, 128, 0)');
|
||||
});
|
||||
|
||||
itFailsFirefox(
|
||||
'should throw when added with content to the CSP page',
|
||||
async () => {
|
||||
it('should throw when added with content to the CSP page', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/csp.html');
|
||||
@ -1892,8 +1886,7 @@ describe('Page', function () {
|
||||
return (error = error_);
|
||||
});
|
||||
expect(error).toBeTruthy();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw when added with URL to the CSP page', async () => {
|
||||
const {page, server} = getTestState();
|
||||
@ -1921,7 +1914,7 @@ describe('Page', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Page.setJavaScriptEnabled', function () {
|
||||
describe('Page.setJavaScriptEnabled', function () {
|
||||
it('should work', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
@ -1962,9 +1955,7 @@ describe('Page', function () {
|
||||
]);
|
||||
expect(nonCachedRequest.headers['if-modified-since']).toBe(undefined);
|
||||
});
|
||||
itFailsFirefox(
|
||||
'should stay disabled when toggling request interception on/off',
|
||||
async () => {
|
||||
it('should stay disabled when toggling request interception on/off', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.setCacheEnabled(false);
|
||||
@ -1977,8 +1968,7 @@ describe('Page', function () {
|
||||
page.reload(),
|
||||
]);
|
||||
expect(nonCachedRequest.headers['if-modified-since']).toBe(undefined);
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('printing to PDF', function () {
|
||||
@ -2220,9 +2210,7 @@ describe('Page', function () {
|
||||
expect(error.message).toContain('Values must be strings');
|
||||
});
|
||||
// @see https://github.com/puppeteer/puppeteer/issues/3327
|
||||
itFailsFirefox(
|
||||
'should work when re-defining top-level Event class',
|
||||
async () => {
|
||||
it('should work when re-defining top-level Event class', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/input/select.html');
|
||||
@ -2241,12 +2229,11 @@ describe('Page', function () {
|
||||
return (globalThis as any).result.onChange;
|
||||
})
|
||||
).toEqual(['blue']);
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Page.Events.Close', function () {
|
||||
itFailsFirefox('should work with window.close', async () => {
|
||||
it('should work with window.close', async () => {
|
||||
const {page, context} = getTestState();
|
||||
|
||||
const newPagePromise = new Promise<Page>(fulfill => {
|
||||
|
@ -17,15 +17,12 @@
|
||||
import expect from 'expect';
|
||||
import http from 'http';
|
||||
import os from 'os';
|
||||
import {
|
||||
getTestState,
|
||||
describeFailsFirefox,
|
||||
itFailsWindows,
|
||||
} from './mocha-utils.js';
|
||||
import {getTestState} from './mocha-utils.js';
|
||||
import type {Server, IncomingMessage, ServerResponse} from 'http';
|
||||
import type {Browser} from '../../lib/cjs/puppeteer/common/Browser.js';
|
||||
import type {AddressInfo} from 'net';
|
||||
import {TestServer} from '../../utils/testserver/lib/index.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
let HOSTNAME = os.hostname();
|
||||
|
||||
@ -53,7 +50,7 @@ function getEmptyPageUrl(server: TestServer): string {
|
||||
return `http://${HOSTNAME}:${server.PORT}${emptyPagePath}`;
|
||||
}
|
||||
|
||||
describeFailsFirefox('request proxy', () => {
|
||||
describe('request proxy', () => {
|
||||
let browser: Browser;
|
||||
let proxiedRequestUrls: string[];
|
||||
let proxyServer: Server;
|
||||
@ -194,9 +191,7 @@ describeFailsFirefox('request proxy', () => {
|
||||
/**
|
||||
* See issues #7873, #7719, and #7698.
|
||||
*/
|
||||
itFailsWindows(
|
||||
'should proxy requests when configured at context level',
|
||||
async () => {
|
||||
it('should proxy requests when configured at context level', async () => {
|
||||
const {puppeteer, defaultBrowserOptions, server} = getTestState();
|
||||
const emptyPageUrl = getEmptyPageUrl(server);
|
||||
|
||||
@ -214,8 +209,7 @@ describeFailsFirefox('request proxy', () => {
|
||||
expect(response.ok()).toBe(true);
|
||||
|
||||
expect(proxiedRequestUrls).toEqual([emptyPageUrl]);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should respect proxy bypass list when configured at context level', async () => {
|
||||
const {puppeteer, defaultBrowserOptions, server} = getTestState();
|
||||
|
@ -20,6 +20,7 @@ import {
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
} from './mocha-utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describe('Query handler tests', function () {
|
||||
setupTestBrowserHooks();
|
||||
|
@ -20,6 +20,7 @@ import {
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
} from './mocha-utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describe('querySelector', function () {
|
||||
setupTestBrowserHooks();
|
||||
|
@ -22,7 +22,6 @@ import {
|
||||
getTestState,
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
describeFailsFirefox,
|
||||
} from './mocha-utils.js';
|
||||
import {ConsoleMessage} from '../../lib/cjs/puppeteer/common/ConsoleMessage.js';
|
||||
import {
|
||||
@ -30,11 +29,12 @@ import {
|
||||
HTTPRequest,
|
||||
InterceptResolutionAction,
|
||||
} from '../../lib/cjs/puppeteer/common/HTTPRequest.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describe('request interception', function () {
|
||||
setupTestBrowserHooks();
|
||||
setupTestPageAndContextHooks();
|
||||
describeFailsFirefox('Page.setRequestInterception', function () {
|
||||
describe('Page.setRequestInterception', function () {
|
||||
const expectedActions: ActionResult[] = ['abort', 'continue', 'respond'];
|
||||
while (expectedActions.length > 0) {
|
||||
const expectedAction = expectedActions.pop();
|
||||
@ -709,7 +709,7 @@ describe('request interception', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Request.continue', function () {
|
||||
describe('Request.continue', function () {
|
||||
it('should work', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -805,7 +805,7 @@ describe('request interception', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Request.respond', function () {
|
||||
describe('Request.respond', function () {
|
||||
it('should work', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
|
@ -22,15 +22,15 @@ import {
|
||||
getTestState,
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
describeFailsFirefox,
|
||||
} from './mocha-utils.js';
|
||||
import {HTTPRequest} from '../../lib/cjs/puppeteer/common/HTTPRequest.js';
|
||||
import {ConsoleMessage} from '../../lib/cjs/puppeteer/common/ConsoleMessage.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describe('request interception', function () {
|
||||
setupTestBrowserHooks();
|
||||
setupTestPageAndContextHooks();
|
||||
describeFailsFirefox('Page.setRequestInterception', function () {
|
||||
describe('Page.setRequestInterception', function () {
|
||||
it('should intercept', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -623,7 +623,7 @@ describe('request interception', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Request.continue', function () {
|
||||
describe('Request.continue', function () {
|
||||
it('should work', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -739,7 +739,7 @@ describe('request interception', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describeFailsFirefox('Request.respond', function () {
|
||||
describe('Request.respond', function () {
|
||||
it('should work', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
|
@ -19,17 +19,15 @@ import {
|
||||
getTestState,
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
itFailsFirefox,
|
||||
itHeadfulOnly,
|
||||
itChromeOnly,
|
||||
} from './mocha-utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describe('Screenshots', function () {
|
||||
setupTestBrowserHooks();
|
||||
setupTestPageAndContextHooks();
|
||||
|
||||
describe('Page.screenshot', function () {
|
||||
itFailsFirefox('should work', async () => {
|
||||
it('should work', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.setViewport({width: 500, height: 500});
|
||||
@ -37,7 +35,7 @@ describe('Screenshots', function () {
|
||||
const screenshot = await page.screenshot();
|
||||
expect(screenshot).toBeGolden('screenshot-sanity.png');
|
||||
});
|
||||
itFailsFirefox('should clip rect', async () => {
|
||||
it('should clip rect', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.setViewport({width: 500, height: 500});
|
||||
@ -52,7 +50,7 @@ describe('Screenshots', function () {
|
||||
});
|
||||
expect(screenshot).toBeGolden('screenshot-clip-rect.png');
|
||||
});
|
||||
itFailsFirefox('should use scale for clip', async () => {
|
||||
it('should use scale for clip', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.setViewport({width: 500, height: 500});
|
||||
@ -68,9 +66,7 @@ describe('Screenshots', function () {
|
||||
});
|
||||
expect(screenshot).toBeGolden('screenshot-clip-rect-scale2.png');
|
||||
});
|
||||
itFailsFirefox(
|
||||
'should get screenshot bigger than the viewport',
|
||||
async () => {
|
||||
it('should get screenshot bigger than the viewport', async () => {
|
||||
const {page, server} = getTestState();
|
||||
await page.setViewport({width: 50, height: 50});
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
@ -83,8 +79,7 @@ describe('Screenshots', function () {
|
||||
},
|
||||
});
|
||||
expect(screenshot).toBeGolden('screenshot-offscreen-clip.png');
|
||||
}
|
||||
);
|
||||
});
|
||||
it('should run in parallel', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
@ -106,7 +101,7 @@ describe('Screenshots', function () {
|
||||
const screenshots = await Promise.all(promises);
|
||||
expect(screenshots[1]!).toBeGolden('grid-cell-1.png');
|
||||
});
|
||||
itFailsFirefox('should take fullPage screenshots', async () => {
|
||||
it('should take fullPage screenshots', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.setViewport({width: 500, height: 500});
|
||||
@ -147,7 +142,7 @@ describe('Screenshots', function () {
|
||||
})
|
||||
);
|
||||
});
|
||||
itFailsFirefox('should allow transparency', async () => {
|
||||
it('should allow transparency', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.setViewport({width: 100, height: 100});
|
||||
@ -155,7 +150,7 @@ describe('Screenshots', function () {
|
||||
const screenshot = await page.screenshot({omitBackground: true});
|
||||
expect(screenshot).toBeGolden('transparent.png');
|
||||
});
|
||||
itFailsFirefox('should render white background on jpeg file', async () => {
|
||||
it('should render white background on jpeg file', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.setViewport({width: 100, height: 100});
|
||||
@ -166,7 +161,7 @@ describe('Screenshots', function () {
|
||||
});
|
||||
expect(screenshot).toBeGolden('white.jpg');
|
||||
});
|
||||
itFailsFirefox('should work with webp', async () => {
|
||||
it('should work with webp', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.setViewport({width: 100, height: 100});
|
||||
@ -190,7 +185,7 @@ describe('Screenshots', function () {
|
||||
});
|
||||
expect(screenshot).toBeGolden('screenshot-clip-odd-size.png');
|
||||
});
|
||||
itFailsFirefox('should return base64', async () => {
|
||||
it('should return base64', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.setViewport({width: 500, height: 500});
|
||||
@ -206,7 +201,7 @@ describe('Screenshots', function () {
|
||||
'screenshot-sanity.png'
|
||||
);
|
||||
});
|
||||
itHeadfulOnly('should work in "fromSurface: false" mode', async () => {
|
||||
it('should work in "fromSurface: false" mode', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.setViewport({width: 500, height: 500});
|
||||
@ -231,7 +226,7 @@ describe('Screenshots', function () {
|
||||
const screenshot = await elementHandle.screenshot();
|
||||
expect(screenshot).toBeGolden('screenshot-element-bounding-box.png');
|
||||
});
|
||||
itChromeOnly('should work with a null viewport', async () => {
|
||||
it('should work with a null viewport', async () => {
|
||||
const {defaultBrowserOptions, puppeteer, server} = getTestState();
|
||||
|
||||
const browser = await puppeteer.launch({
|
||||
@ -271,9 +266,7 @@ describe('Screenshots', function () {
|
||||
const screenshot = await elementHandle.screenshot();
|
||||
expect(screenshot).toBeGolden('screenshot-element-padding-border.png');
|
||||
});
|
||||
itFailsFirefox(
|
||||
'should capture full element when larger than viewport',
|
||||
async () => {
|
||||
it('should capture full element when larger than viewport', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
await page.setViewport({width: 500, height: 500});
|
||||
@ -307,8 +300,7 @@ describe('Screenshots', function () {
|
||||
};
|
||||
})
|
||||
).toEqual({w: 500, h: 500});
|
||||
}
|
||||
);
|
||||
});
|
||||
it('should scroll element into view', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
@ -336,7 +328,7 @@ describe('Screenshots', function () {
|
||||
'screenshot-element-scrolled-into-view.png'
|
||||
);
|
||||
});
|
||||
itFailsFirefox('should work with a rotated element', async () => {
|
||||
it('should work with a rotated element', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
await page.setViewport({width: 500, height: 500});
|
||||
@ -351,7 +343,7 @@ describe('Screenshots', function () {
|
||||
const screenshot = await elementHandle.screenshot();
|
||||
expect(screenshot).toBeGolden('screenshot-element-rotate.png');
|
||||
});
|
||||
itFailsFirefox('should fail to screenshot a detached element', async () => {
|
||||
it('should fail to screenshot a detached element', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
await page.setContent('<h1>remove this</h1>');
|
||||
@ -386,7 +378,7 @@ describe('Screenshots', function () {
|
||||
const screenshot = await elementHandle.screenshot();
|
||||
expect(screenshot).toBeGolden('screenshot-element-fractional.png');
|
||||
});
|
||||
itFailsFirefox('should work for an element with an offset', async () => {
|
||||
it('should work for an element with an offset', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
await page.setContent(
|
||||
|
@ -20,11 +20,12 @@ import {Page} from '../../lib/cjs/puppeteer/common/Page.js';
|
||||
import {Target} from '../../lib/cjs/puppeteer/common/Target.js';
|
||||
import {
|
||||
getTestState,
|
||||
itFailsFirefox,
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
} from './mocha-utils.js';
|
||||
import utils from './utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
const {waitEvent} = utils;
|
||||
|
||||
describe('Target', function () {
|
||||
@ -79,7 +80,7 @@ describe('Target', function () {
|
||||
).toBe('Hello world');
|
||||
expect(await originalPage.$('body')).toBeTruthy();
|
||||
});
|
||||
itFailsFirefox('should be able to use async waitForTarget', async () => {
|
||||
it('should be able to use async waitForTarget', async () => {
|
||||
const {page, server, context} = getTestState();
|
||||
|
||||
const [otherPage] = await Promise.all([
|
||||
@ -101,9 +102,7 @@ describe('Target', function () {
|
||||
);
|
||||
expect(page).not.toEqual(otherPage);
|
||||
});
|
||||
itFailsFirefox(
|
||||
'should report when a new page is created and closed',
|
||||
async () => {
|
||||
it('should report when a new page is created and closed', async () => {
|
||||
const {page, server, context} = getTestState();
|
||||
|
||||
const [otherPage] = await Promise.all([
|
||||
@ -145,11 +144,8 @@ describe('Target', function () {
|
||||
)) as Page[];
|
||||
expect(allPages).toContain(page);
|
||||
expect(allPages).not.toContain(otherPage);
|
||||
}
|
||||
);
|
||||
itFailsFirefox(
|
||||
'should report when a service worker is created and destroyed',
|
||||
async () => {
|
||||
});
|
||||
it('should report when a service worker is created and destroyed', async () => {
|
||||
const {page, server, context} = getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -181,9 +177,8 @@ describe('Target', function () {
|
||||
});
|
||||
});
|
||||
expect(await destroyedTarget).toBe(await createdTarget);
|
||||
}
|
||||
);
|
||||
itFailsFirefox('should create a worker from a service worker', async () => {
|
||||
});
|
||||
it('should create a worker from a service worker', async () => {
|
||||
const {page, server, context} = getTestState();
|
||||
|
||||
await page.goto(server.PREFIX + '/serviceworkers/empty/sw.html');
|
||||
@ -198,7 +193,7 @@ describe('Target', function () {
|
||||
})
|
||||
).toBe('[object ServiceWorkerGlobalScope]');
|
||||
});
|
||||
itFailsFirefox('should create a worker from a shared worker', async () => {
|
||||
it('should create a worker from a shared worker', async () => {
|
||||
const {page, server, context} = getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -215,7 +210,7 @@ describe('Target', function () {
|
||||
})
|
||||
).toBe('[object SharedWorkerGlobalScope]');
|
||||
});
|
||||
itFailsFirefox('should report when a target url changes', async () => {
|
||||
it('should report when a target url changes', async () => {
|
||||
const {page, server, context} = getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -235,7 +230,7 @@ describe('Target', function () {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
expect((await changedTarget).url()).toBe(server.EMPTY_PAGE);
|
||||
});
|
||||
itFailsFirefox('should not report uninitialized pages', async () => {
|
||||
it('should not report uninitialized pages', async () => {
|
||||
const {context} = getTestState();
|
||||
|
||||
let targetChanged = false;
|
||||
@ -268,9 +263,7 @@ describe('Target', function () {
|
||||
expect(targetChanged).toBe(false);
|
||||
context.removeListener('targetchanged', listener);
|
||||
});
|
||||
itFailsFirefox(
|
||||
'should not crash while redirecting if original request was missed',
|
||||
async () => {
|
||||
it('should not crash while redirecting if original request was missed', async () => {
|
||||
const {page, server, context} = getTestState();
|
||||
|
||||
let serverResponse!: ServerResponse;
|
||||
@ -296,9 +289,8 @@ describe('Target', function () {
|
||||
await waitEvent(newPage, 'load');
|
||||
// Cleanup.
|
||||
await newPage.close();
|
||||
}
|
||||
);
|
||||
itFailsFirefox('should have an opener', async () => {
|
||||
});
|
||||
it('should have an opener', async () => {
|
||||
const {page, server, context} = getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -318,7 +310,7 @@ describe('Target', function () {
|
||||
});
|
||||
|
||||
describe('Browser.waitForTarget', () => {
|
||||
itFailsFirefox('should wait for a target', async () => {
|
||||
it('should wait for a target', async () => {
|
||||
const {browser, puppeteer, server} = getTestState();
|
||||
|
||||
let resolved = false;
|
||||
|
@ -19,10 +19,10 @@ import {
|
||||
getTestState,
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
describeFailsFirefox,
|
||||
} from './mocha-utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describeFailsFirefox('Touchscreen', function () {
|
||||
describe('Touchscreen', function () {
|
||||
setupTestBrowserHooks();
|
||||
setupTestPageAndContextHooks();
|
||||
|
||||
|
@ -17,11 +17,12 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import expect from 'expect';
|
||||
import {getTestState, describeChromeOnly} from './mocha-utils.js';
|
||||
import {getTestState} from './mocha-utils.js';
|
||||
import {Browser} from '../../lib/cjs/puppeteer/common/Browser.js';
|
||||
import {Page} from '../../lib/cjs/puppeteer/common/Page.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describeChromeOnly('Tracing', function () {
|
||||
describe('Tracing', function () {
|
||||
let outputFile!: string;
|
||||
let browser!: Browser;
|
||||
let page!: Page;
|
||||
|
@ -18,11 +18,11 @@ import expect from 'expect';
|
||||
import {isErrorLike} from '../../lib/cjs/puppeteer/util/ErrorLike.js';
|
||||
import {
|
||||
getTestState,
|
||||
itFailsFirefox,
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
} from './mocha-utils.js';
|
||||
import {attachFrame, detachFrame} from './utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describe('waittask specs', function () {
|
||||
setupTestBrowserHooks();
|
||||
@ -188,7 +188,7 @@ describe('waittask specs', function () {
|
||||
});
|
||||
await watchdog;
|
||||
});
|
||||
itFailsFirefox('should work with strict CSP policy', async () => {
|
||||
it('should work with strict CSP policy', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
server.setCSP('/empty.html', 'script-src ' + server.PREFIX);
|
||||
@ -421,7 +421,7 @@ describe('waittask specs', function () {
|
||||
await frame.waitForSelector('div');
|
||||
});
|
||||
|
||||
itFailsFirefox('should work with removed MutationObserver', async () => {
|
||||
it('should work with removed MutationObserver', async () => {
|
||||
const {page} = getTestState();
|
||||
|
||||
await page.evaluate(() => {
|
||||
@ -465,9 +465,7 @@ describe('waittask specs', function () {
|
||||
await watchdog;
|
||||
});
|
||||
|
||||
itFailsFirefox(
|
||||
'Page.waitForSelector is shortcut for main frame',
|
||||
async () => {
|
||||
it('Page.waitForSelector is shortcut for main frame', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -478,10 +476,9 @@ describe('waittask specs', function () {
|
||||
await page.evaluate(addElement, 'div');
|
||||
const eHandle = await watchdog;
|
||||
expect(eHandle?.frame).toBe(page.mainFrame());
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
itFailsFirefox('should run in specified frame', async () => {
|
||||
it('should run in specified frame', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await attachFrame(page, 'frame1', server.EMPTY_PAGE);
|
||||
@ -495,7 +492,7 @@ describe('waittask specs', function () {
|
||||
expect(eHandle?.frame).toBe(frame2);
|
||||
});
|
||||
|
||||
itFailsFirefox('should throw when frame is detached', async () => {
|
||||
it('should throw when frame is detached', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await attachFrame(page, 'frame1', server.EMPTY_PAGE);
|
||||
@ -738,7 +735,7 @@ describe('waittask specs', function () {
|
||||
'waiting for selector `.//div` failed: timeout 10ms exceeded'
|
||||
);
|
||||
});
|
||||
itFailsFirefox('should run in specified frame', async () => {
|
||||
it('should run in specified frame', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await attachFrame(page, 'frame1', server.EMPTY_PAGE);
|
||||
@ -751,7 +748,7 @@ describe('waittask specs', function () {
|
||||
const eHandle = await waitForXPathPromise;
|
||||
expect(eHandle?.frame).toBe(frame2);
|
||||
});
|
||||
itFailsFirefox('should throw when frame is detached', async () => {
|
||||
it('should throw when frame is detached', async () => {
|
||||
const {page, server} = getTestState();
|
||||
|
||||
await attachFrame(page, 'frame1', server.EMPTY_PAGE);
|
||||
|
@ -18,14 +18,14 @@ import expect from 'expect';
|
||||
import {ConsoleMessage} from '../../lib/cjs/puppeteer/common/ConsoleMessage.js';
|
||||
import {WebWorker} from '../../lib/cjs/puppeteer/common/WebWorker.js';
|
||||
import {
|
||||
describeFailsFirefox,
|
||||
getTestState,
|
||||
setupTestBrowserHooks,
|
||||
setupTestPageAndContextHooks,
|
||||
} from './mocha-utils.js';
|
||||
import {waitEvent} from './utils.js';
|
||||
import {it} from './mocha-utils.js';
|
||||
|
||||
describeFailsFirefox('Workers', function () {
|
||||
describe('Workers', function () {
|
||||
setupTestBrowserHooks();
|
||||
setupTestPageAndContextHooks();
|
||||
it('Page.workers', async () => {
|
||||
|
@ -9,7 +9,8 @@
|
||||
},
|
||||
"include": ["src"],
|
||||
"references": [
|
||||
{"path": "../tsconfig.lib.json"},
|
||||
{"path": "../utils/testserver/tsconfig.json"}
|
||||
{"path": "../src/tsconfig.cjs.json"},
|
||||
{"path": "../utils/testserver/tsconfig.json"},
|
||||
{"path": "../utils/mochaRunner/tsconfig.json"}
|
||||
]
|
||||
}
|
||||
|
47
utils/mochaRunner/README.md
Normal file
47
utils/mochaRunner/README.md
Normal file
@ -0,0 +1,47 @@
|
||||
# Mocha Runner
|
||||
|
||||
Mocha Runner is a test runner on top of mocha. It uses `/test/TestSuites.json` and `/test/TestExpectations.json` files to run mocha tests in multiple configurations and interpret results.
|
||||
|
||||
## Running tests for Mocha Runner itself.
|
||||
|
||||
```
|
||||
npm run build:dev && npx c8 node utils/mochaRunner/lib/test.js
|
||||
```
|
||||
|
||||
## Running tests using Mocha Runner
|
||||
|
||||
```
|
||||
npm run build:dev && npm run test
|
||||
```
|
||||
|
||||
By default, the runner runs all test suites applicable to the current platform.
|
||||
To pick a test suite, provide the `--test-suite` arguments. For example,
|
||||
|
||||
```
|
||||
npm run build:dev && npm run test -- --test-suite chrome-headless
|
||||
```
|
||||
|
||||
## TestSuites.json
|
||||
|
||||
Define test suites via the `testSuites` attribute. `parameters` can be used in the `TestExpectations.json` to disable tests
|
||||
based on parameters. The meaning for parameters is defined in `parameterDefinitons` which tell what env object corresponds
|
||||
to the given parameter.
|
||||
|
||||
## TestExpectations.json
|
||||
|
||||
An expectation looks like this:
|
||||
|
||||
```
|
||||
{
|
||||
"testIdPattern": "[accessibility.spec]",
|
||||
"platforms": ["darwin", "win32", "linux"],
|
||||
"parameters": ["firefox"],
|
||||
"expectations": ["SKIP"]
|
||||
}
|
||||
```
|
||||
|
||||
`testIdPattern` defines a string that will be used to prefix-match tests. `platforms` defines the platforms the expectation is for (`or`-logic).
|
||||
`parameters` defines the parameters that the test has to match (`and`-logic). `expectations` is the list of test results that are considered to be acceptable.
|
||||
|
||||
Currently, expectations are updated manually. The test runner outputs the suggested changes to the expectation file if the test run does not match
|
||||
expectations.
|
204
utils/mochaRunner/src/main.ts
Normal file
204
utils/mochaRunner/src/main.ts
Normal file
@ -0,0 +1,204 @@
|
||||
import {
|
||||
TestExpectation,
|
||||
MochaResults,
|
||||
zTestSuiteFile,
|
||||
zPlatform,
|
||||
TestSuite,
|
||||
TestSuiteFile,
|
||||
Platform,
|
||||
} from './types.js';
|
||||
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import os from 'os';
|
||||
import {spawn} from 'node:child_process';
|
||||
import {
|
||||
extendProcessEnv,
|
||||
filterByPlatform,
|
||||
prettyPrintJSON,
|
||||
readJSON,
|
||||
filterByParameters,
|
||||
getExpectationUpdates,
|
||||
getSkippedTests,
|
||||
} from './utils.js';
|
||||
|
||||
function getApplicableTestSuites(
|
||||
parsedSuitesFile: TestSuiteFile,
|
||||
platform: Platform
|
||||
): TestSuite[] {
|
||||
const testSuiteArgIdx = process.argv.indexOf('--test-suite');
|
||||
let applicableSuites: TestSuite[] = [];
|
||||
|
||||
if (testSuiteArgIdx === -1) {
|
||||
applicableSuites = filterByPlatform(parsedSuitesFile.testSuites, platform);
|
||||
} else {
|
||||
const testSuiteId = process.argv[testSuiteArgIdx + 1];
|
||||
const testSuite = parsedSuitesFile.testSuites.find(suite => {
|
||||
return suite.id === testSuiteId;
|
||||
});
|
||||
|
||||
if (!testSuite) {
|
||||
console.error(`Test suite ${testSuiteId} is not defined`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (!testSuite.platforms.includes(platform)) {
|
||||
console.warn(
|
||||
`Test suite ${testSuiteId} is not enabled for your platform. Running it anyway.`
|
||||
);
|
||||
}
|
||||
|
||||
applicableSuites = [testSuite];
|
||||
}
|
||||
|
||||
return applicableSuites;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const platform = zPlatform.parse(os.platform());
|
||||
|
||||
const expectations = readJSON(
|
||||
path.join(process.cwd(), 'test', 'TestExpectations.json')
|
||||
) as TestExpectation[];
|
||||
|
||||
const parsedSuitesFile = zTestSuiteFile.parse(
|
||||
readJSON(path.join(process.cwd(), 'test', 'TestSuites.json'))
|
||||
);
|
||||
|
||||
const applicableSuites = getApplicableTestSuites(parsedSuitesFile, platform);
|
||||
|
||||
console.log('Planning to run the following test suites', applicableSuites);
|
||||
|
||||
let fail = false;
|
||||
const recommendations = [];
|
||||
try {
|
||||
for (const suite of applicableSuites) {
|
||||
const parameters = suite.parameters;
|
||||
|
||||
const applicableExpectations = filterByParameters(
|
||||
filterByPlatform(expectations, platform),
|
||||
parameters
|
||||
);
|
||||
|
||||
const skippedTests = getSkippedTests(applicableExpectations);
|
||||
|
||||
const env = extendProcessEnv([
|
||||
...parameters.map(param => {
|
||||
return parsedSuitesFile.parameterDefinitons[param];
|
||||
}),
|
||||
{
|
||||
PUPPETEER_SKIPPED_TEST_CONFIG: JSON.stringify(
|
||||
skippedTests.map(ex => {
|
||||
return ex.testIdPattern;
|
||||
})
|
||||
),
|
||||
},
|
||||
]);
|
||||
|
||||
const tmpDir = fs.mkdtempSync(
|
||||
path.join(os.tmpdir(), 'puppeteer-test-runner-')
|
||||
);
|
||||
const tmpFilename = path.join(tmpDir, 'output.json');
|
||||
console.log('Running', JSON.stringify(parameters), tmpFilename);
|
||||
const handle = spawn(
|
||||
'npx mocha',
|
||||
['--reporter=json', '--reporter-option', 'output=' + tmpFilename],
|
||||
{
|
||||
shell: true,
|
||||
cwd: process.cwd(),
|
||||
stdio: 'inherit',
|
||||
env,
|
||||
}
|
||||
);
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
handle.on('error', err => {
|
||||
reject(err);
|
||||
});
|
||||
handle.on('close', () => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
console.log('Finished', JSON.stringify(parameters));
|
||||
try {
|
||||
const results = readJSON(tmpFilename) as MochaResults;
|
||||
console.log('Results from mocha');
|
||||
console.log('Stats', JSON.stringify(results.stats));
|
||||
results.pending.length > 0 && console.log('# Pending tests');
|
||||
for (const test of results.pending) {
|
||||
console.log(`\t? ${test.fullTitle} ${test.file}`);
|
||||
}
|
||||
results.failures.length > 0 && console.log('# Failed tests');
|
||||
for (const test of results.failures) {
|
||||
console.log(`\tF ${test.fullTitle} ${test.file}`, test.err);
|
||||
}
|
||||
const recommendation = getExpectationUpdates(
|
||||
results,
|
||||
applicableExpectations,
|
||||
{
|
||||
platforms: [os.platform()],
|
||||
parameters,
|
||||
}
|
||||
);
|
||||
if (recommendation.length > 0) {
|
||||
fail = true;
|
||||
recommendations.push(...recommendation);
|
||||
} else {
|
||||
console.log('Test run matches expecations');
|
||||
continue;
|
||||
}
|
||||
} catch (err) {
|
||||
fail = true;
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
fail = true;
|
||||
console.error(err);
|
||||
} finally {
|
||||
const toAdd = recommendations.filter(item => {
|
||||
return item.action === 'add';
|
||||
});
|
||||
if (toAdd.length) {
|
||||
console.log(
|
||||
'Add the following to TestExpecations.json to ignore the error:'
|
||||
);
|
||||
prettyPrintJSON(
|
||||
toAdd.map(item => {
|
||||
return item.expectation;
|
||||
})
|
||||
);
|
||||
}
|
||||
const toRemove = recommendations.filter(item => {
|
||||
return item.action === 'remove';
|
||||
});
|
||||
if (toRemove.length) {
|
||||
console.log(
|
||||
'Remove the following from the TestExpecations.json to ignore the error:'
|
||||
);
|
||||
prettyPrintJSON(
|
||||
toRemove.map(item => {
|
||||
return item.expectation;
|
||||
})
|
||||
);
|
||||
}
|
||||
const toUpdate = recommendations.filter(item => {
|
||||
return item.action === 'update';
|
||||
});
|
||||
if (toUpdate.length) {
|
||||
console.log(
|
||||
'Update the following expectations in the TestExpecations.json to ignore the error:'
|
||||
);
|
||||
prettyPrintJSON(
|
||||
toUpdate.map(item => {
|
||||
return item.expectation;
|
||||
})
|
||||
);
|
||||
}
|
||||
process.exit(fail ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(error => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
46
utils/mochaRunner/src/test.ts
Normal file
46
utils/mochaRunner/src/test.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import assert from 'assert/strict';
|
||||
import test from 'node:test';
|
||||
import {filterByParameters, getTestResultForFailure} from './utils.js';
|
||||
import {TestExpectation} from './types.js';
|
||||
import {getFilename, extendProcessEnv} from './utils.js';
|
||||
|
||||
test('extendProcessEnv', () => {
|
||||
const env = extendProcessEnv([{TEST: 'TEST'}, {TEST2: 'TEST2'}]);
|
||||
assert.equal(env['TEST'], 'TEST');
|
||||
assert.equal(env['TEST2'], 'TEST2');
|
||||
});
|
||||
|
||||
test('getFilename', () => {
|
||||
assert.equal(getFilename('/etc/test.ts'), 'test');
|
||||
assert.equal(getFilename('/etc/test.js'), 'test');
|
||||
});
|
||||
|
||||
test('getTestResultForFailure', () => {
|
||||
assert.equal(
|
||||
getTestResultForFailure({err: {code: 'ERR_MOCHA_TIMEOUT'}}),
|
||||
'TIMEOUT'
|
||||
);
|
||||
assert.equal(getTestResultForFailure({err: {code: 'ERROR'}}), 'FAIL');
|
||||
});
|
||||
|
||||
test('filterByParameters', () => {
|
||||
const expectations: TestExpectation[] = [
|
||||
{
|
||||
testIdPattern:
|
||||
'[oopif.spec] OOPIF "after all" hook for "should keep track of a frames OOP state"',
|
||||
platforms: ['darwin'],
|
||||
parameters: ['firefox', 'headless'],
|
||||
expectations: ['FAIL'],
|
||||
},
|
||||
];
|
||||
assert.equal(
|
||||
filterByParameters(expectations, ['firefox', 'headless']).length,
|
||||
1
|
||||
);
|
||||
assert.equal(filterByParameters(expectations, ['firefox']).length, 0);
|
||||
assert.equal(
|
||||
filterByParameters(expectations, ['firefox', 'headless', 'other']).length,
|
||||
1
|
||||
);
|
||||
assert.equal(filterByParameters(expectations, ['other']).length, 0);
|
||||
});
|
42
utils/mochaRunner/src/types.ts
Normal file
42
utils/mochaRunner/src/types.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import {z} from 'zod';
|
||||
|
||||
export const zPlatform = z.enum(['win32', 'linux', 'darwin']);
|
||||
|
||||
export type Platform = z.infer<typeof zPlatform>;
|
||||
|
||||
export const zTestSuite = z.object({
|
||||
id: z.string(),
|
||||
platforms: z.array(zPlatform),
|
||||
parameters: z.array(z.string()),
|
||||
});
|
||||
|
||||
export type TestSuite = z.infer<typeof zTestSuite>;
|
||||
|
||||
export const zTestSuiteFile = z.object({
|
||||
testSuites: z.array(zTestSuite),
|
||||
parameterDefinitons: z.record(z.any()),
|
||||
});
|
||||
|
||||
export type TestSuiteFile = z.infer<typeof zTestSuiteFile>;
|
||||
|
||||
export type TestResult = 'PASS' | 'FAIL' | 'TIMEOUT' | 'SKIP';
|
||||
|
||||
export type TestExpectation = {
|
||||
testIdPattern: string;
|
||||
platforms: NodeJS.Platform[];
|
||||
parameters: string[];
|
||||
expectations: TestResult[];
|
||||
};
|
||||
|
||||
export type MochaTestResult = {
|
||||
fullTitle: string;
|
||||
file: string;
|
||||
err?: {code: string};
|
||||
};
|
||||
|
||||
export type MochaResults = {
|
||||
stats: unknown;
|
||||
pending: MochaTestResult[];
|
||||
passes: MochaTestResult[];
|
||||
failures: MochaTestResult[];
|
||||
};
|
153
utils/mochaRunner/src/utils.ts
Normal file
153
utils/mochaRunner/src/utils.ts
Normal file
@ -0,0 +1,153 @@
|
||||
import {
|
||||
MochaTestResult,
|
||||
TestExpectation,
|
||||
MochaResults,
|
||||
TestResult,
|
||||
} from './types.js';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
|
||||
export function extendProcessEnv(envs: object[]): NodeJS.ProcessEnv {
|
||||
return envs.reduce(
|
||||
(acc: object, item: object) => {
|
||||
Object.assign(acc, item);
|
||||
return acc;
|
||||
},
|
||||
{
|
||||
...process.env,
|
||||
}
|
||||
) as NodeJS.ProcessEnv;
|
||||
}
|
||||
|
||||
export function getFilename(file: string): string {
|
||||
return path.basename(file).replace(path.extname(file), '');
|
||||
}
|
||||
|
||||
export function readJSON(path: string): unknown {
|
||||
return JSON.parse(fs.readFileSync(path, 'utf-8'));
|
||||
}
|
||||
|
||||
export function filterByPlatform<T extends {platforms: NodeJS.Platform[]}>(
|
||||
items: T[],
|
||||
platform: NodeJS.Platform
|
||||
): T[] {
|
||||
return items.filter(item => {
|
||||
return item.platforms.includes(platform);
|
||||
});
|
||||
}
|
||||
|
||||
export function prettyPrintJSON(json: unknown): void {
|
||||
console.log(JSON.stringify(json, null, 2));
|
||||
}
|
||||
|
||||
export function filterByParameters(
|
||||
expecations: TestExpectation[],
|
||||
parameters: string[]
|
||||
): TestExpectation[] {
|
||||
const querySet = new Set(parameters);
|
||||
return expecations.filter(ex => {
|
||||
return ex.parameters.every(param => {
|
||||
return querySet.has(param);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The last expectation that matches the startsWith filter wins.
|
||||
*/
|
||||
export function findEffectiveExpecationForTest(
|
||||
expectations: TestExpectation[],
|
||||
result: MochaTestResult
|
||||
): TestExpectation | undefined {
|
||||
return expectations
|
||||
.filter(expecation => {
|
||||
if (
|
||||
getTestId(result.file, result.fullTitle).startsWith(
|
||||
expecation.testIdPattern
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
})
|
||||
.pop();
|
||||
}
|
||||
|
||||
type RecommendedExpecation = {
|
||||
expectation: TestExpectation;
|
||||
test: MochaTestResult;
|
||||
action: 'remove' | 'add' | 'update';
|
||||
};
|
||||
|
||||
export function getExpectationUpdates(
|
||||
results: MochaResults,
|
||||
expecations: TestExpectation[],
|
||||
context: {
|
||||
platforms: NodeJS.Platform[];
|
||||
parameters: string[];
|
||||
}
|
||||
): RecommendedExpecation[] {
|
||||
const output: RecommendedExpecation[] = [];
|
||||
|
||||
for (const pass of results.passes) {
|
||||
const expectation = findEffectiveExpecationForTest(expecations, pass);
|
||||
if (expectation && !expectation.expectations.includes('PASS')) {
|
||||
output.push({
|
||||
expectation,
|
||||
test: pass,
|
||||
action: 'remove',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
for (const failure of results.failures) {
|
||||
const expectation = findEffectiveExpecationForTest(expecations, failure);
|
||||
if (expectation) {
|
||||
if (
|
||||
!expectation.expectations.includes(getTestResultForFailure(failure))
|
||||
) {
|
||||
output.push({
|
||||
expectation: {
|
||||
...expectation,
|
||||
expectations: [
|
||||
...expectation.expectations,
|
||||
getTestResultForFailure(failure),
|
||||
],
|
||||
},
|
||||
test: failure,
|
||||
action: 'update',
|
||||
});
|
||||
}
|
||||
} else {
|
||||
output.push({
|
||||
expectation: {
|
||||
testIdPattern: getTestId(failure.file, failure.fullTitle),
|
||||
platforms: context.platforms,
|
||||
parameters: context.parameters,
|
||||
expectations: [getTestResultForFailure(failure)],
|
||||
},
|
||||
test: failure,
|
||||
action: 'add',
|
||||
});
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
export function getTestResultForFailure(
|
||||
test: Pick<MochaTestResult, 'err'>
|
||||
): TestResult {
|
||||
return test.err?.code === 'ERR_MOCHA_TIMEOUT' ? 'TIMEOUT' : 'FAIL';
|
||||
}
|
||||
|
||||
export function getSkippedTests(
|
||||
expectations: TestExpectation[]
|
||||
): TestExpectation[] {
|
||||
return expectations.filter(ex => {
|
||||
return ex.expectations.includes('SKIP');
|
||||
});
|
||||
}
|
||||
|
||||
export function getTestId(file: string, fullTitle: string): string {
|
||||
return `[${getFilename(file)}] ${fullTitle}`;
|
||||
}
|
11
utils/mochaRunner/tsconfig.json
Normal file
11
utils/mochaRunner/tsconfig.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"composite": true,
|
||||
"module": "CommonJS",
|
||||
"outDir": "lib",
|
||||
"rootDir": "src"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
Loading…
Reference in New Issue
Block a user