chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,687 @@
|
||||
import type { Server } from 'node:http';
|
||||
import http from 'node:http';
|
||||
import type { AddressInfo } from 'node:net';
|
||||
import { promisify } from 'node:util';
|
||||
|
||||
import type { CommonLibrary, UnwrapPromise } from '@crawlee/browser-pool';
|
||||
import {
|
||||
LaunchContext,
|
||||
PlaywrightBrowser,
|
||||
PlaywrightController,
|
||||
PlaywrightPlugin,
|
||||
PuppeteerController,
|
||||
PuppeteerPlugin,
|
||||
} from '@crawlee/browser-pool';
|
||||
import playwright from 'playwright';
|
||||
import type { Server as ProxyChainServer } from 'proxy-chain';
|
||||
import type { Browser } from 'puppeteer';
|
||||
import puppeteer from 'puppeteer';
|
||||
|
||||
import { runExampleComServer } from '../../shared/_helper';
|
||||
import { createProxyServer } from './create-proxy-server';
|
||||
|
||||
// Firefox browser launch is significantly slower than Chromium/WebKit (~12s vs <1s).
|
||||
// Under CPU load from parallel tests, it can exceed 2 minutes. Use 5 minute timeout.
|
||||
vitest.setConfig({ testTimeout: 300_000 });
|
||||
|
||||
let port: number;
|
||||
let server: Server;
|
||||
let serverAddress = 'http://localhost:';
|
||||
|
||||
beforeAll(async () => {
|
||||
[server, port] = await runExampleComServer();
|
||||
serverAddress += port;
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
server.close();
|
||||
});
|
||||
|
||||
const runPluginTest = <
|
||||
P extends typeof PlaywrightPlugin | typeof PuppeteerPlugin,
|
||||
C extends typeof PuppeteerController | typeof PlaywrightController,
|
||||
L extends CommonLibrary,
|
||||
>(
|
||||
Plugin: P,
|
||||
Controller: C,
|
||||
library: L,
|
||||
) => {
|
||||
describe(`${library.constructor.name} - ${'name' in library ? library.name!() : ''} general`, () => {
|
||||
test.concurrent('should launch browser', async () => {
|
||||
const plugin = new Plugin(library as never);
|
||||
const browser = await plugin.launch();
|
||||
try {
|
||||
expect(typeof browser.newPage).toBe('function');
|
||||
expect(typeof browser.close).toBe('function');
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
});
|
||||
|
||||
test.concurrent('should create launch context', () => {
|
||||
const plugin = new Plugin(library as never);
|
||||
const id = 'abc';
|
||||
const launchOptions = { foo: 'bar' };
|
||||
const proxyUrl = 'http://proxy.com/';
|
||||
const context = plugin.createLaunchContext({
|
||||
id,
|
||||
// @ts-expect-error Testing options
|
||||
launchOptions,
|
||||
});
|
||||
|
||||
expect(context).toBeInstanceOf(LaunchContext);
|
||||
|
||||
context.proxyUrl = proxyUrl;
|
||||
context.extend({
|
||||
one: 1,
|
||||
});
|
||||
|
||||
const desiredObject = {
|
||||
id,
|
||||
launchOptions,
|
||||
browserPlugin: plugin,
|
||||
_proxyUrl: proxyUrl.slice(0, -1),
|
||||
one: 1,
|
||||
useIncognitoPages: false,
|
||||
};
|
||||
|
||||
// expect(context).toMatchObject(desiredObject)
|
||||
// Switch to this after the issue with `TypeError: prop.startsWith is not a function` is solved.
|
||||
|
||||
expect(context.id).toEqual(desiredObject.id);
|
||||
expect(context.launchOptions).toEqual(desiredObject.launchOptions);
|
||||
expect(context.browserPlugin).toEqual(desiredObject.browserPlugin);
|
||||
expect(context['_proxyUrl']).toEqual(desiredObject._proxyUrl); // eslint-disable-line
|
||||
expect(context.one).toEqual(desiredObject.one);
|
||||
expect(context.useIncognitoPages).toEqual(desiredObject.useIncognitoPages);
|
||||
});
|
||||
|
||||
test.concurrent('should get default launchContext values from plugin options', async () => {
|
||||
const proxyUrl = 'http://apify1234@10.10.10.0:8080/';
|
||||
|
||||
const plugin = new Plugin(library as never, {
|
||||
proxyUrl,
|
||||
userDataDir: 'test',
|
||||
useIncognitoPages: true,
|
||||
});
|
||||
|
||||
const context = plugin.createLaunchContext();
|
||||
|
||||
expect(context.proxyUrl).toEqual(proxyUrl.slice(0, -1));
|
||||
expect(context.useIncognitoPages).toBeTruthy();
|
||||
expect(context.userDataDir).toEqual('test');
|
||||
});
|
||||
|
||||
test.concurrent('should allow unsetting launchContext proxyUrl', () => {
|
||||
const plugin = new Plugin(library as never);
|
||||
const context = plugin.createLaunchContext();
|
||||
|
||||
context.proxyUrl = 'http://proxy.com/';
|
||||
expect(context.proxyUrl).toEqual('http://proxy.com');
|
||||
|
||||
context.proxyUrl = undefined;
|
||||
expect(context.proxyUrl).toBeUndefined();
|
||||
});
|
||||
|
||||
test.concurrent('should create browser controller', () => {
|
||||
const plugin = new Plugin(library as never);
|
||||
const browserController = plugin.createController();
|
||||
expect(browserController).toBeInstanceOf(Controller);
|
||||
});
|
||||
|
||||
test.concurrent('should work with cookies', async () => {
|
||||
const plugin = new Plugin(library as never);
|
||||
const browserController = plugin.createController();
|
||||
const context = plugin.createLaunchContext();
|
||||
|
||||
const browser = await plugin.launch(context as never);
|
||||
|
||||
try {
|
||||
browserController.assignBrowser(browser as never, context as never);
|
||||
browserController.activate();
|
||||
|
||||
const page = await browserController.newPage();
|
||||
await browserController.setCookies(page as never, [
|
||||
{ name: 'TEST', value: 'TESTER-COOKIE', url: serverAddress },
|
||||
]);
|
||||
await page.goto(serverAddress, { waitUntil: 'domcontentloaded' });
|
||||
|
||||
const cookies = await browserController.getCookies(page as never);
|
||||
expect(cookies[0].name).toBe('TEST');
|
||||
expect(cookies[0].value).toBe('TESTER-COOKIE');
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
});
|
||||
|
||||
test.concurrent('newPage options cannot be used with persistent context', async () => {
|
||||
const plugin = new Plugin(library as never);
|
||||
const browserController = plugin.createController();
|
||||
|
||||
const context = plugin.createLaunchContext({
|
||||
useIncognitoPages: false,
|
||||
});
|
||||
|
||||
const browser = await plugin.launch(context as never);
|
||||
try {
|
||||
browserController.assignBrowser(browser as never, context as never);
|
||||
browserController.activate();
|
||||
|
||||
try {
|
||||
const page = await browserController.newPage({});
|
||||
await page.close();
|
||||
|
||||
expect(false).toBe(true);
|
||||
} catch (error: any) {
|
||||
expect(error.message).toBe(
|
||||
'A new page can be created with provided context only when using incognito pages or experimental containers.',
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
describe('Plugins', () => {
|
||||
let target: http.Server;
|
||||
let unprotectedProxy: ProxyChainServer;
|
||||
let protectedProxy: ProxyChainServer;
|
||||
|
||||
beforeAll(async () => {
|
||||
target = http.createServer((request, response) => {
|
||||
response.end(request.socket.remoteAddress);
|
||||
});
|
||||
await promisify(target.listen.bind(target) as any)(0, '127.0.0.1');
|
||||
|
||||
unprotectedProxy = createProxyServer('127.0.0.2', '', '');
|
||||
await unprotectedProxy.listen();
|
||||
|
||||
protectedProxy = createProxyServer('127.0.0.3', 'foo', 'bar');
|
||||
await protectedProxy.listen();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await promisify(target.close.bind(target))();
|
||||
|
||||
await unprotectedProxy.close(false);
|
||||
await protectedProxy.close(false);
|
||||
});
|
||||
|
||||
describe('Puppeteer specifics', () => {
|
||||
test.concurrent('should work with non authenticated proxyUrl', async () => {
|
||||
const proxyUrl = `http://127.0.0.2:${unprotectedProxy.port}`;
|
||||
const plugin = new PuppeteerPlugin(puppeteer);
|
||||
|
||||
const context = plugin.createLaunchContext({
|
||||
proxyUrl,
|
||||
launchOptions: {
|
||||
args: [
|
||||
// Exclude loopback interface from proxy bypass list,
|
||||
// so the request to localhost goes through proxy.
|
||||
// This way there's no need for a 3rd party server.
|
||||
'--proxy-bypass-list=<-loopback>',
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const browser = await plugin.launch(context);
|
||||
|
||||
try {
|
||||
const page = await browser.newPage();
|
||||
const response = await page.goto(`http://127.0.0.1:${(target.address() as AddressInfo).port}`);
|
||||
|
||||
const text = await response!.text();
|
||||
|
||||
expect(text).toBe('127.0.0.2');
|
||||
|
||||
await page.close();
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
});
|
||||
|
||||
test.concurrent('should work with authenticated proxyUrl', async () => {
|
||||
const proxyUrl = `http://foo:bar@127.0.0.3:${protectedProxy.port}`;
|
||||
const plugin = new PuppeteerPlugin(puppeteer);
|
||||
|
||||
const context = plugin.createLaunchContext({
|
||||
proxyUrl,
|
||||
launchOptions: {
|
||||
args: [
|
||||
// Exclude loopback interface from proxy bypass list,
|
||||
// so the request to localhost goes through proxy.
|
||||
// This way there's no need for a 3rd party server.
|
||||
'--proxy-bypass-list=<-loopback>',
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const browser = await plugin.launch(context);
|
||||
|
||||
try {
|
||||
const page = await browser.newPage();
|
||||
const response = await page.goto(`http://127.0.0.1:${(target.address() as AddressInfo).port}`);
|
||||
|
||||
const text = await response!.text();
|
||||
|
||||
expect(text).toBe('127.0.0.3');
|
||||
|
||||
await page.close();
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
});
|
||||
|
||||
test.concurrent('should use persistent context by default', async () => {
|
||||
const plugin = new PuppeteerPlugin(puppeteer);
|
||||
const browserController = plugin.createController();
|
||||
|
||||
const launchContext = plugin.createLaunchContext();
|
||||
|
||||
const browser = await plugin.launch(launchContext);
|
||||
try {
|
||||
browserController.assignBrowser(browser, launchContext);
|
||||
browserController.activate();
|
||||
|
||||
const page = await browserController.newPage();
|
||||
const browserContext = page.browserContext();
|
||||
|
||||
expect(browserContext.id).toBeFalsy();
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
});
|
||||
|
||||
test.concurrent('should use incognito pages by option', async () => {
|
||||
const plugin = new PuppeteerPlugin(puppeteer);
|
||||
const browserController = plugin.createController();
|
||||
|
||||
const launchContext = plugin.createLaunchContext({ useIncognitoPages: true });
|
||||
|
||||
const browser = await plugin.launch(launchContext);
|
||||
try {
|
||||
browserController.assignBrowser(browser, launchContext);
|
||||
browserController.activate();
|
||||
|
||||
const page = await browserController.newPage();
|
||||
const browserContext = page.browserContext();
|
||||
|
||||
expect(browserContext.id).toBeTruthy();
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
});
|
||||
|
||||
test.concurrent('should allow calling functions on the proxied browser', async () => {
|
||||
const plugin = new PuppeteerPlugin(puppeteer);
|
||||
const launchContext = plugin.createLaunchContext();
|
||||
const browser = await plugin.launch(launchContext);
|
||||
|
||||
try {
|
||||
await expect(browser.pages()).resolves.toBeDefined();
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
});
|
||||
|
||||
test.concurrent('should pass launch options to browser', async () => {
|
||||
const plugin = new PuppeteerPlugin(puppeteer);
|
||||
|
||||
const userAgent = 'HelloWorld';
|
||||
|
||||
const launchOptions = {
|
||||
args: [`--user-agent=${userAgent}`],
|
||||
};
|
||||
|
||||
const launchContext = plugin.createLaunchContext({ launchOptions });
|
||||
const browser = await plugin.launch(launchContext);
|
||||
|
||||
try {
|
||||
expect(await browser.userAgent()).toBe(userAgent);
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
});
|
||||
|
||||
test.concurrent('proxyUsername and proxyPassword as newPage options', async () => {
|
||||
const plugin = new PuppeteerPlugin(puppeteer);
|
||||
const browserController = new PuppeteerController(plugin);
|
||||
|
||||
const launchContext = plugin.createLaunchContext({
|
||||
useIncognitoPages: true,
|
||||
});
|
||||
|
||||
const browser = await plugin.launch(launchContext);
|
||||
try {
|
||||
browserController.assignBrowser(browser, launchContext);
|
||||
browserController.activate();
|
||||
|
||||
const page = await browserController.newPage({
|
||||
proxyServer: `http://127.0.0.3:${protectedProxy.port}`,
|
||||
proxyUsername: 'foo',
|
||||
proxyPassword: 'bar',
|
||||
proxyBypassList: ['<-loopback>'],
|
||||
});
|
||||
|
||||
const response = await page.goto(`http://127.0.0.1:${(target.address() as AddressInfo).port}`);
|
||||
const text = await response!.text();
|
||||
|
||||
expect(text).toBe('127.0.0.3');
|
||||
|
||||
await page.close();
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
runPluginTest(PuppeteerPlugin, PuppeteerController, puppeteer);
|
||||
|
||||
describe('normalizeProxyOptions', () => {
|
||||
test.each([
|
||||
['socks5://user:pass@proxy.example.com:1080', 'socks5://proxy.example.com:1080'],
|
||||
['http://user:pass@proxy.example.com:8080', 'http://proxy.example.com:8080'],
|
||||
])('PlaywrightController should handle %s', (proxyUrl, expectedServer) => {
|
||||
const plugin = new PlaywrightPlugin(playwright.chromium);
|
||||
const browserController = new PlaywrightController(plugin);
|
||||
|
||||
const result = browserController.normalizeProxyOptions(proxyUrl, {});
|
||||
|
||||
expect(result).toMatchObject({
|
||||
proxy: { server: expectedServer, username: 'user', password: 'pass' },
|
||||
});
|
||||
});
|
||||
|
||||
test.each([
|
||||
['socks5://user:pass@proxy.example.com:1080', 'socks5://proxy.example.com:1080'],
|
||||
['http://user:pass@proxy.example.com:8080', 'http://proxy.example.com:8080'],
|
||||
])('PuppeteerController should handle %s', (proxyUrl, expectedServer) => {
|
||||
const plugin = new PuppeteerPlugin(puppeteer);
|
||||
const browserController = new PuppeteerController(plugin);
|
||||
|
||||
const result = browserController.normalizeProxyOptions(proxyUrl, {});
|
||||
|
||||
expect(result).toMatchObject({
|
||||
proxyServer: expectedServer,
|
||||
proxyUsername: 'user',
|
||||
proxyPassword: 'pass',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Playwright specifics', () => {
|
||||
let browser: playwright.Browser;
|
||||
|
||||
afterEach(async () => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
describe.each(['chromium', 'firefox', 'webkit'] as const)('with %s', (browserName) => {
|
||||
test('should work with non authenticated proxyUrl', async () => {
|
||||
const proxyUrl = `http://127.0.0.2:${unprotectedProxy.port}`;
|
||||
const plugin = new PlaywrightPlugin(playwright[browserName]);
|
||||
|
||||
const launchOptions =
|
||||
browserName === 'chromium'
|
||||
? {
|
||||
args: [
|
||||
// Exclude loopback interface from proxy bypass list,
|
||||
// so the request to localhost goes through proxy.
|
||||
// This way there's no need for a 3rd party server.
|
||||
'--proxy-bypass-list=<-loopback>',
|
||||
],
|
||||
}
|
||||
: undefined;
|
||||
|
||||
const context = plugin.createLaunchContext({
|
||||
proxyUrl,
|
||||
launchOptions,
|
||||
});
|
||||
|
||||
browser = await plugin.launch(context);
|
||||
expect(context.launchOptions!.proxy!.server).toEqual(proxyUrl);
|
||||
|
||||
const page = await browser.newPage();
|
||||
const response = await page.goto(`http://127.0.0.1:${(target.address() as AddressInfo).port}`);
|
||||
const text = await response!.text();
|
||||
|
||||
expect(text).toBe('127.0.0.2');
|
||||
|
||||
await page.close();
|
||||
});
|
||||
|
||||
test('should work with authenticated proxyUrl', async () => {
|
||||
const proxyUrl = `http://foo:bar@127.0.0.3:${protectedProxy.port}`;
|
||||
const plugin = new PlaywrightPlugin(playwright[browserName]);
|
||||
|
||||
const launchOptions =
|
||||
browserName === 'chromium'
|
||||
? {
|
||||
args: [
|
||||
// Exclude loopback interface from proxy bypass list,
|
||||
// so the request to localhost goes through proxy.
|
||||
// This way there's no need for a 3rd party server.
|
||||
'--proxy-bypass-list=<-loopback>',
|
||||
],
|
||||
}
|
||||
: undefined;
|
||||
|
||||
const context = plugin.createLaunchContext({
|
||||
proxyUrl,
|
||||
launchOptions,
|
||||
});
|
||||
|
||||
browser = await plugin.launch(context);
|
||||
|
||||
const page = await browser.newPage();
|
||||
const response = await page.goto(`http://127.0.0.1:${(target.address() as AddressInfo).port}`);
|
||||
const text = await response!.text();
|
||||
|
||||
expect(text).toBe('127.0.0.3');
|
||||
|
||||
await page.close();
|
||||
});
|
||||
|
||||
test('proxy as newPage option', async () => {
|
||||
const plugin = new PlaywrightPlugin(playwright.chromium);
|
||||
const browserController = new PlaywrightController(plugin);
|
||||
|
||||
const launchContext = plugin.createLaunchContext({
|
||||
useIncognitoPages: true,
|
||||
});
|
||||
|
||||
browser = await plugin.launch(launchContext);
|
||||
browserController.assignBrowser(browser, launchContext);
|
||||
browserController.activate();
|
||||
|
||||
const page = await browserController.newPage({
|
||||
proxy: {
|
||||
server: `http://127.0.0.3:${protectedProxy.port}`,
|
||||
username: 'foo',
|
||||
password: 'bar',
|
||||
bypass: '<-loopback>',
|
||||
},
|
||||
});
|
||||
|
||||
const response = await page.goto(`http://127.0.0.1:${(target.address() as AddressInfo).port}`);
|
||||
const text = await response!.text();
|
||||
|
||||
expect(text).toBe('127.0.0.3');
|
||||
|
||||
await page.close();
|
||||
});
|
||||
|
||||
test('should use incognito context by option', async () => {
|
||||
const plugin = new PlaywrightPlugin(playwright[browserName]);
|
||||
const browserController = plugin.createController();
|
||||
|
||||
const launchContext = plugin.createLaunchContext({ useIncognitoPages: true });
|
||||
|
||||
browser = await plugin.launch(launchContext);
|
||||
browserController.assignBrowser(browser, launchContext);
|
||||
browserController.activate();
|
||||
|
||||
const page = await browserController.newPage();
|
||||
const browserContext = page.context();
|
||||
await browserController.newPage();
|
||||
|
||||
expect(browserContext.pages()).toHaveLength(1);
|
||||
});
|
||||
|
||||
test('should use persistent context by default', async () => {
|
||||
const plugin = new PlaywrightPlugin(playwright[browserName]);
|
||||
const browserController = plugin.createController();
|
||||
|
||||
const launchContext = plugin.createLaunchContext();
|
||||
|
||||
browser = await plugin.launch(launchContext);
|
||||
browserController.assignBrowser(browser, launchContext);
|
||||
browserController.activate();
|
||||
|
||||
const page = await browserController.newPage();
|
||||
const context = page.context();
|
||||
await browserController.newPage();
|
||||
|
||||
expect(context.pages()).toHaveLength(3); // 3 pages because of the about:blank.
|
||||
});
|
||||
|
||||
test('should pass launch options to browser', async () => {
|
||||
const plugin = new PlaywrightPlugin(playwright[browserName]);
|
||||
|
||||
let ran = false;
|
||||
|
||||
const launchOptions = {
|
||||
logger: {
|
||||
isEnabled: () => {
|
||||
ran = true;
|
||||
return false;
|
||||
},
|
||||
log: () => {},
|
||||
},
|
||||
};
|
||||
|
||||
const launchContext = plugin.createLaunchContext({ launchOptions });
|
||||
browser = await plugin.launch(launchContext);
|
||||
|
||||
expect(ran).toBe(true);
|
||||
});
|
||||
|
||||
describe('PlaywrightBrowser', () => {
|
||||
test('should create new page', async () => {
|
||||
const plugin = new PlaywrightPlugin(playwright[browserName]);
|
||||
|
||||
const launchContext = plugin.createLaunchContext();
|
||||
browser = await plugin.launch(launchContext);
|
||||
const page = await browser.newPage();
|
||||
|
||||
expect(typeof page.close).toBe('function');
|
||||
expect(typeof page.evaluate).toBe('function');
|
||||
});
|
||||
|
||||
test('should emit disconnected event on close', async () => {
|
||||
const plugin = new PlaywrightPlugin(playwright[browserName]);
|
||||
|
||||
const launchContext = plugin.createLaunchContext();
|
||||
browser = await plugin.launch(launchContext);
|
||||
let called = false;
|
||||
|
||||
browser.on('disconnected', () => {
|
||||
called = true;
|
||||
});
|
||||
|
||||
await browser.close();
|
||||
|
||||
expect(called).toBe(true);
|
||||
});
|
||||
|
||||
test('should be used only with incognito pages context', async () => {
|
||||
const plugin = new PlaywrightPlugin(playwright[browserName]);
|
||||
|
||||
const launchContext = plugin.createLaunchContext({ useIncognitoPages: false });
|
||||
browser = await plugin.launch(launchContext);
|
||||
expect(browser).toBeInstanceOf(PlaywrightBrowser);
|
||||
|
||||
await browser.close();
|
||||
|
||||
const launchContext2 = plugin.createLaunchContext({ useIncognitoPages: true });
|
||||
browser = await plugin.launch(launchContext2);
|
||||
expect(browser).not.toBeInstanceOf(PlaywrightBrowser);
|
||||
});
|
||||
|
||||
test('should return correct version', async () => {
|
||||
const plugin = new PlaywrightPlugin(playwright[browserName]);
|
||||
|
||||
const launchContext = plugin.createLaunchContext({ useIncognitoPages: false });
|
||||
browser = await plugin.launch(launchContext);
|
||||
const version1 = browser.version();
|
||||
|
||||
await browser.close();
|
||||
|
||||
const launchContext2 = plugin.createLaunchContext({ useIncognitoPages: true });
|
||||
browser = await plugin.launch(launchContext2);
|
||||
expect(version1).toEqual(browser.version());
|
||||
});
|
||||
|
||||
test('should return all contexts', async () => {
|
||||
const plugin = new PlaywrightPlugin(playwright[browserName]);
|
||||
|
||||
const launchContext = plugin.createLaunchContext();
|
||||
browser = await plugin.launch(launchContext);
|
||||
const contexts = browser.contexts();
|
||||
expect(contexts).toHaveLength(1);
|
||||
|
||||
// Cast to any to access private property
|
||||
expect(contexts[0]).toEqual((browser as any)._browserContext);
|
||||
});
|
||||
|
||||
test('should return correct connected status', async () => {
|
||||
const plugin = new PlaywrightPlugin(playwright[browserName]);
|
||||
|
||||
const launchContext = plugin.createLaunchContext();
|
||||
browser = await plugin.launch(launchContext);
|
||||
expect(browser.isConnected()).toBe(true);
|
||||
|
||||
await browser.close();
|
||||
|
||||
expect(browser.isConnected()).toBe(false);
|
||||
});
|
||||
|
||||
test('should throw on newContext call', async () => {
|
||||
const plugin = new PlaywrightPlugin(playwright[browserName]);
|
||||
const launchContext = plugin.createLaunchContext();
|
||||
browser = await plugin.launch(launchContext);
|
||||
|
||||
await expect(browser.newContext()).rejects.toThrow(
|
||||
'Function `newContext()` is not available in incognito mode',
|
||||
);
|
||||
});
|
||||
|
||||
test('should have same public interface as playwright browserType', async () => {
|
||||
const plugin = new PlaywrightPlugin(playwright[browserName]);
|
||||
const originalFunctionNames = [
|
||||
'close',
|
||||
'contexts',
|
||||
'isConnected',
|
||||
'newContext',
|
||||
'newPage',
|
||||
'version',
|
||||
] as const;
|
||||
const launchContext = plugin.createLaunchContext({ useIncognitoPages: true });
|
||||
browser = await plugin.launch(launchContext);
|
||||
|
||||
for (const originalFunctionName of originalFunctionNames) {
|
||||
expect(typeof browser[originalFunctionName]).toBe('function');
|
||||
}
|
||||
|
||||
expect.hasAssertions();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
runPluginTest(PlaywrightPlugin, PlaywrightController, playwright.chromium);
|
||||
runPluginTest(PlaywrightPlugin, PlaywrightController, playwright.firefox);
|
||||
runPluginTest(PlaywrightPlugin, PlaywrightController, playwright.webkit);
|
||||
});
|
||||
Reference in New Issue
Block a user