test: migrate cli tests to new folio (#6048)

This commit is contained in:
Dmitry Gozman 2021-04-02 11:19:26 -07:00 committed by GitHub
parent 561cb23e8d
commit d0afa9d8de
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 396 additions and 297 deletions

View file

@ -14,16 +14,18 @@
* limitations under the License.
*/
import { folio } from './cli.fixtures';
import { test, expect } from '../config/cliTest';
import * as http from 'http';
const { it, describe, expect } = folio;
test.describe('cli codegen', () => {
test.beforeEach(async ({ mode, browserName, headful }) => {
test.skip(mode !== 'default');
test.fixme(browserName === 'firefox' && headful, 'Focus is off');
});
test('should click', async ({ page, openRecorder }) => {
const recorder = await openRecorder();
describe('cli codegen', (suite, { browserName, headful, mode }) => {
suite.skip(mode !== 'default');
suite.fixme(browserName === 'firefox' && headful, 'Focus is off');
}, () => {
it('should click', async ({ page, recorder }) => {
await recorder.setContentAndWait(`<button onclick="console.log('click')">Submit</button>`);
const selector = await recorder.hoverOverElement('button');
@ -58,7 +60,9 @@ await page.ClickAsync("text=Submit");`);
expect(message.text()).toBe('click');
});
it('should click after same-document navigation', async ({ page, recorder, httpServer }) => {
test('should click after same-document navigation', async ({ page, openRecorder, httpServer }) => {
const recorder = await openRecorder();
httpServer.setHandler((req: http.IncomingMessage, res: http.ServerResponse) => {
res.setHeader('Content-Type', 'text/html; charset=utf-8');
res.end('');
@ -87,7 +91,9 @@ await page.ClickAsync("text=Submit");`);
expect(message.text()).toBe('click');
});
it('should work with TrustedTypes', async ({ page, recorder }) => {
test('should work with TrustedTypes', async ({ page, openRecorder }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait(`
<head>
<meta http-equiv="Content-Security-Policy" content="trusted-types unsafe escape; require-trusted-types-for 'script'">
@ -128,7 +134,9 @@ await page.ClickAsync("text=Submit");`);
expect(message.text()).toBe('click');
});
it('should not target selector preview by text regexp', async ({ page, recorder }) => {
test('should not target selector preview by text regexp', async ({ page, openRecorder }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait(`<span>dummy</span>`);
// Force highlight.
@ -160,7 +168,9 @@ await page.ClickAsync("text=Submit");`);
expect(message.text()).toBe('click');
});
it('should fill', async ({ page, recorder }) => {
test('should fill', async ({ page, openRecorder }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait(`<input id="input" name="name" oninput="console.log(input.value)"></input>`);
const selector = await recorder.focusElement('input');
expect(selector).toBe('input[name="name"]');
@ -193,7 +203,9 @@ await page.FillAsync(\"input[name=\\\"name\\\"]\", \"John\");`);
expect(message.text()).toBe('John');
});
it('should fill textarea', async ({ page, recorder }) => {
test('should fill textarea', async ({ page, openRecorder }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait(`<textarea id="textarea" name="name" oninput="console.log(textarea.value)"></textarea>`);
const selector = await recorder.focusElement('textarea');
expect(selector).toBe('textarea[name="name"]');
@ -209,7 +221,9 @@ await page.FillAsync(\"input[name=\\\"name\\\"]\", \"John\");`);
expect(message.text()).toBe('John');
});
it('should press', async ({ page, recorder }) => {
test('should press', async ({ page, openRecorder }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait(`<input name="name" onkeypress="console.log('press')"></input>`);
const selector = await recorder.focusElement('input');
@ -246,7 +260,9 @@ await page.PressAsync(\"input[name=\\\"name\\\"]\", \"Shift+Enter\");`);
expect(messages[0].text()).toBe('press');
});
it('should update selected element after pressing Tab', async ({ page, recorder }) => {
test('should update selected element after pressing Tab', async ({ page, openRecorder }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait(`
<input name="one"></input>
<input name="two"></input>
@ -276,7 +292,9 @@ await page.PressAsync(\"input[name=\\\"name\\\"]\", \"Shift+Enter\");`);
await page.fill('input[name="two"]', 'barfoo321');`);
});
it('should record ArrowDown', async ({ page, recorder }) => {
test('should record ArrowDown', async ({ page, openRecorder }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait(`<input name="name" onkeydown="console.log('press:' + event.key)"></input>`);
const selector = await recorder.focusElement('input');
@ -297,7 +315,9 @@ await page.PressAsync(\"input[name=\\\"name\\\"]\", \"Shift+Enter\");`);
expect(messages[0].text()).toBe('press:ArrowDown');
});
it('should emit single keyup on ArrowDown', async ({ page, recorder }) => {
test('should emit single keyup on ArrowDown', async ({ page, openRecorder }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait(`<input name="name" onkeydown="console.log('down:' + event.key)" onkeyup="console.log('up:' + event.key)"></input>`);
const selector = await recorder.focusElement('input');
@ -320,7 +340,9 @@ await page.PressAsync(\"input[name=\\\"name\\\"]\", \"Shift+Enter\");`);
expect(messages[1].text()).toBe('up:ArrowDown');
});
it('should check', async ({ page, recorder }) => {
test('should check', async ({ page, openRecorder }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait(`<input id="checkbox" type="checkbox" name="accept" onchange="console.log(checkbox.checked)"></input>`);
const selector = await recorder.focusElement('input');
@ -355,7 +377,9 @@ await page.CheckAsync(\"input[name=\\\"accept\\\"]\");`);
expect(message.text()).toBe('true');
});
it('should check with keyboard', async ({ page, recorder }) => {
test('should check with keyboard', async ({ page, openRecorder }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait(`<input id="checkbox" type="checkbox" name="accept" onchange="console.log(checkbox.checked)"></input>`);
const selector = await recorder.focusElement('input');
@ -373,7 +397,9 @@ await page.CheckAsync(\"input[name=\\\"accept\\\"]\");`);
expect(message.text()).toBe('true');
});
it('should uncheck', async ({ page, recorder }) => {
test('should uncheck', async ({ page, openRecorder }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait(`<input id="checkbox" type="checkbox" checked name="accept" onchange="console.log(checkbox.checked)"></input>`);
const selector = await recorder.focusElement('input');
@ -408,7 +434,9 @@ await page.UncheckAsync(\"input[name=\\\"accept\\\"]\");`);
expect(message.text()).toBe('false');
});
it('should select', async ({ page, recorder }) => {
test('should select', async ({ page, openRecorder }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait('<select id="age" onchange="console.log(age.selectedOptions[0].value)"><option value="1"><option value="2"></select>');
const selector = await recorder.hoverOverElement('select');
@ -443,9 +471,10 @@ await page.SelectOptionAsync(\"select\", \"2\");`);
expect(message.text()).toBe('2');
});
it('should await popup', (test, { browserName, headful }) => {
test('should await popup', async ({ page, openRecorder, browserName, headful }) => {
test.fixme(browserName === 'webkit' && headful, 'Middle click does not open a popup in our webkit embedder');
}, async ({ page, recorder }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait('<a target=_blank rel=noopener href="about:blank">link</a>');
const selector = await recorder.hoverOverElement('a');
@ -491,7 +520,9 @@ await Task.WhenAll(
expect(popup.url()).toBe('about:blank');
});
it('should assert navigation', async ({ page, recorder }) => {
test('should assert navigation', async ({ page, openRecorder }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait(`<a onclick="window.location.href='about:blank#foo'">link</a>`);
const selector = await recorder.hoverOverElement('a');
@ -531,7 +562,9 @@ await page.ClickAsync(\"text=link\");
});
it('should await navigation', async ({ page, recorder }) => {
test('should await navigation', async ({ page, openRecorder }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait(`<a onclick="setTimeout(() => window.location.href='about:blank#foo', 1000)">link</a>`);
const selector = await recorder.hoverOverElement('a');

View file

@ -14,16 +14,18 @@
* limitations under the License.
*/
import { folio } from './cli.fixtures';
import { test, expect } from '../config/cliTest';
import * as http from 'http';
import * as url from 'url';
const { it, describe, expect } = folio;
test.describe('cli codegen', () => {
test.beforeEach(async ({ mode }) => {
test.skip(mode !== 'default');
});
test('should contain open page', async ({ openRecorder }) => {
const recorder = await openRecorder();
describe('cli codegen', (suite, { mode }) => {
suite.skip(mode !== 'default');
}, () => {
it('should contain open page', async ({ recorder }) => {
await recorder.setContentAndWait(``);
const sources = await recorder.waitForOutput('<javascript>', `page.goto`);
@ -48,9 +50,11 @@ describe('cli codegen', (suite, { mode }) => {
var page = await context.NewPageAsync();`);
});
it('should contain second page', async ({ context, recorder }) => {
test('should contain second page', async ({ openRecorder, page }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait(``);
await context.newPage();
await page.context().newPage();
const sources = await recorder.waitForOutput('<javascript>', 'page1');
expect(sources.get('<javascript>').text).toContain(`
@ -74,9 +78,11 @@ var page = await context.NewPageAsync();`);
var page1 = await context.NewPageAsync();`);
});
it('should contain close page', async ({ context, recorder }) => {
test('should contain close page', async ({ openRecorder, page }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait(``);
await context.newPage();
await page.context().newPage();
await recorder.page.close();
const sources = await recorder.waitForOutput('<javascript>', 'page.close();');
@ -96,9 +102,11 @@ var page1 = await context.NewPageAsync();`);
await page.CloseAsync();`);
});
it('should not lead to an error if html gets clicked', async ({ context, recorder }) => {
test('should not lead to an error if html gets clicked', async ({ page, openRecorder }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait('');
await context.newPage();
await page.context().newPage();
const errors: any[] = [];
recorder.page.on('pageerror', e => errors.push(e));
await recorder.page.evaluate(() => document.querySelector('body').remove());
@ -109,9 +117,10 @@ await page.CloseAsync();`);
expect(errors.length).toBe(0);
});
it('should upload a single file', (test, { browserName }) => {
test('should upload a single file', async ({ page, openRecorder, browserName }) => {
test.fixme(browserName === 'firefox', 'Hangs');
}, async ({ page, recorder }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait(`
<form>
<input type="file">
@ -146,9 +155,10 @@ await page.SetInputFilesAsync(\"input[type=\\\"file\\\"]\", \"file-to-upload.txt
});
it('should upload multiple files', (test, { browserName }) => {
test('should upload multiple files', async ({ page, openRecorder, browserName }) => {
test.fixme(browserName === 'firefox', 'Hangs');
}, async ({ page, recorder }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait(`
<form>
<input type="file" multiple>
@ -182,9 +192,10 @@ await page.SetInputFilesAsync(\"input[type=\\\"file\\\"]\", \"file-to-upload.txt
await page.SetInputFilesAsync(\"input[type=\\\"file\\\"]\", new[] { \"file-to-upload.txt\", \"file-to-upload-2.txt\" });`);
});
it('should clear files', (test, { browserName }) => {
test('should clear files', async ({ page, openRecorder, browserName }) => {
test.fixme(browserName === 'firefox', 'Hangs');
}, async ({ page, recorder }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait(`
<form>
<input type="file" multiple>
@ -219,7 +230,9 @@ await page.SetInputFilesAsync(\"input[type=\\\"file\\\"]\", new[] { });`);
});
it('should download files', async ({ page, recorder, httpServer }) => {
test('should download files', async ({ page, openRecorder, httpServer }) => {
const recorder = await openRecorder();
httpServer.setHandler((req: http.IncomingMessage, res: http.ServerResponse) => {
const pathName = url.parse(req.url!).path;
if (pathName === '/download') {
@ -274,7 +287,9 @@ await Task.WhenAll(
page.ClickAsync(\"text=Download\"));`);
});
it('should handle dialogs', async ({ page, recorder }) => {
test('should handle dialogs', async ({ page, openRecorder }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait(`
<button onclick="alert()">click me</button>
`);
@ -325,7 +340,9 @@ await page.ClickAsync(\"text=click me\");`);
});
it('should handle history.postData', async ({ page, recorder, httpServer }) => {
test('should handle history.postData', async ({ page, openRecorder, httpServer }) => {
const recorder = await openRecorder();
httpServer.setHandler((req: http.IncomingMessage, res: http.ServerResponse) => {
res.setHeader('Content-Type', 'text/html; charset=utf-8');
res.end('Hello world');
@ -343,9 +360,10 @@ await page.ClickAsync(\"text=click me\");`);
}
});
it('should record open in a new tab with url', (test, { browserName }) => {
test('should record open in a new tab with url', async ({ page, openRecorder, browserName, platform }) => {
test.fixme(browserName === 'webkit', 'Ctrl+click does not open in new tab on WebKit');
}, async ({ page, recorder, browserName, platform }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait(`<a href="about:blank?foo">link</a>`);
const selector = await recorder.hoverOverElement('a');
@ -371,9 +389,10 @@ await page.ClickAsync(\"text=click me\");`);
}
});
it('should not clash pages', (test, { browserName }) => {
test('should not clash pages', async ({ page, openRecorder, browserName }) => {
test.fixme(browserName === 'firefox', 'Times out on Firefox, maybe the focus issue');
}, async ({ page, recorder }) => {
const recorder = await openRecorder();
const [popup1] = await Promise.all([
page.context().waitForEvent('page'),
page.evaluate(`window.open('about:blank')`)
@ -409,7 +428,9 @@ await page.ClickAsync(\"text=click me\");`);
expect(sources.get('<csharp>').text).toContain(`await page2.FillAsync(\"input\", \"TextB\");`);
});
it('click should emit events in order', async ({ page, recorder }) => {
test('click should emit events in order', async ({ page, openRecorder }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait(`
<button id=button>
<script>
@ -428,7 +449,9 @@ await page.ClickAsync(\"text=click me\");`);
expect(messages).toEqual(['mousedown', 'mouseup', 'click']);
});
it('should update hover model on action', async ({ page, recorder }) => {
test('should update hover model on action', async ({ page, openRecorder }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait(`<input id="checkbox" type="checkbox" name="accept" onchange="checkbox.name='updated'"></input>`);
const [ models ] = await Promise.all([
recorder.waitForActionPerformed(),
@ -437,10 +460,11 @@ await page.ClickAsync(\"text=click me\");`);
expect(models.hovered).toBe('input[name="updated"]');
});
it('should update active model on action', (test, { browserName, headful }) => {
test('should update active model on action', async ({ page, openRecorder, browserName, headful }) => {
test.fixme(browserName === 'webkit' && !headful);
test.fixme(browserName === 'firefox' && !headful);
}, async ({ page, recorder }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait(`<input id="checkbox" type="checkbox" name="accept" onchange="checkbox.name='updated'"></input>`);
const [ models ] = await Promise.all([
recorder.waitForActionPerformed(),
@ -449,7 +473,8 @@ await page.ClickAsync(\"text=click me\");`);
expect(models.active).toBe('input[name="updated"]');
});
it('should check input with chaning id', async ({ page, recorder }) => {
test('should check input with chaning id', async ({ page, openRecorder }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait(`<input id="checkbox" type="checkbox" name="accept" onchange="checkbox.name = 'updated'"></input>`);
await Promise.all([
recorder.waitForActionPerformed(),
@ -457,7 +482,8 @@ await page.ClickAsync(\"text=click me\");`);
]);
});
it('should prefer frame name', async ({ page, recorder, server }) => {
test('should prefer frame name', async ({ page, openRecorder, server }) => {
const recorder = await openRecorder();
await recorder.setContentAndWait(`
<iframe src='./frames/frame.html' name='one'></iframe>
<iframe src='./frames/frame.html' name='two'></iframe>
@ -549,7 +575,8 @@ await page.GetFrame(name: \"two\").ClickAsync(\"text=Hi, I'm frame\");`);
await page.GetFrame(url: \"http://localhost:${server.PORT}/frames/frame.html\").ClickAsync(\"text=Hi, I'm frame\");`);
});
it('should record navigations after identical pushState', async ({ page, recorder, httpServer }) => {
test('should record navigations after identical pushState', async ({ page, openRecorder, httpServer }) => {
const recorder = await openRecorder();
httpServer.setHandler((req: http.IncomingMessage, res: http.ServerResponse) => {
res.setHeader('Content-Type', 'text/html; charset=utf-8');
res.end('Hello world');

View file

@ -16,11 +16,9 @@
import path from 'path';
import fs from 'fs';
import { folio } from './cli.fixtures';
import { test, expect } from '../config/cliTest';
const { it, expect } = folio;
const emptyHTML = new URL('file://' + path.join(__dirname, '..', 'assets', 'empty.html')).toString();
const emptyHTML = new URL('file://' + path.join(__dirname, '..', '..', 'test', 'assets', 'empty.html')).toString();
const launchOptions = (channel: string) => {
return channel ? `headless: false,\n channel: "${channel}"` : 'headless: false';
};
@ -29,7 +27,7 @@ function capitalize(browserName: string): string {
return browserName[0].toUpperCase() + browserName.slice(1);
}
it('should print the correct imports and context options', async ({ browserName, browserChannel, runCLI }) => {
test('should print the correct imports and context options', async ({ browserName, browserChannel, runCLI }) => {
const cli = runCLI(['--target=csharp', emptyHTML]);
const expectedResult = `await Playwright.InstallAsync();
using var playwright = await Playwright.CreateAsync();
@ -41,7 +39,7 @@ var context = await browser.NewContextAsync();`;
expect(cli.text()).toContain(expectedResult);
});
it('should print the correct context options for custom settings', async ({ browserName, browserChannel, runCLI }) => {
test('should print the correct context options for custom settings', async ({ browserName, browserChannel, runCLI }) => {
const cli = runCLI([
'--color-scheme=dark',
'--geolocation=37.819722,-122.478611',
@ -81,9 +79,9 @@ var context = await browser.NewContextAsync(
expect(cli.text()).toContain(expectedResult);
});
it('should print the correct context options when using a device', (test, { browserName }) => {
test('should print the correct context options when using a device', async ({ browserName, browserChannel, runCLI }) => {
test.skip(browserName !== 'chromium');
}, async ({ browserChannel, runCLI }) => {
const cli = runCLI(['--device=Pixel 2', '--target=csharp', emptyHTML]);
const expectedResult = `await Playwright.InstallAsync();
using var playwright = await Playwright.CreateAsync();
@ -95,9 +93,9 @@ var context = await browser.NewContextAsync(playwright.Devices["Pixel 2"]);`;
expect(cli.text()).toContain(expectedResult);
});
it('should print the correct context options when using a device and additional options', (test, { browserName }) => {
test('should print the correct context options when using a device and additional options', async ({ browserName, browserChannel, runCLI }) => {
test.skip(browserName !== 'webkit');
}, async ({ browserChannel, runCLI }) => {
const cli = runCLI([
'--device=iPhone 11',
'--color-scheme=dark',
@ -141,7 +139,7 @@ var context = await browser.NewContextAsync(new BrowserContextOptions(playwright
expect(cli.text()).toContain(expectedResult);
});
it('should print load/save storageState', async ({ browserName, browserChannel, runCLI, testInfo }) => {
test('should print load/save storageState', async ({ browserName, browserChannel, runCLI }, testInfo) => {
const loadFileName = testInfo.outputPath('load.json');
const saveFileName = testInfo.outputPath('save.json');
await fs.promises.writeFile(loadFileName, JSON.stringify({ cookies: [], origins: [] }), 'utf8');

View file

@ -16,16 +16,14 @@
import fs from 'fs';
import path from 'path';
import { folio } from './cli.fixtures';
import { test, expect } from '../config/cliTest';
const { it, expect } = folio;
const emptyHTML = new URL('file://' + path.join(__dirname, '..', 'assets', 'empty.html')).toString();
const emptyHTML = new URL('file://' + path.join(__dirname, '..', '..', 'test', 'assets', 'empty.html')).toString();
const launchOptions = (channel: string) => {
return channel ? `.setHeadless(false)\n .setChannel("${channel}")` : '.setHeadless(false)';
};
it('should print the correct imports and context options', async ({ runCLI, browserChannel, browserName }) => {
test('should print the correct imports and context options', async ({ runCLI, browserChannel, browserName }) => {
const cli = runCLI(['--target=java', emptyHTML]);
const expectedResult = `import com.microsoft.playwright.*;
import com.microsoft.playwright.options.*;
@ -40,7 +38,7 @@ public class Example {
expect(cli.text()).toContain(expectedResult);
});
it('should print the correct context options for custom settings', async ({ runCLI, browserName }) => {
test('should print the correct context options for custom settings', async ({ runCLI, browserName }) => {
const cli = runCLI(['--color-scheme=light', '--target=java', emptyHTML]);
const expectedResult = `BrowserContext context = browser.newContext(new Browser.NewContextOptions()
.setColorScheme(ColorScheme.LIGHT));`;
@ -48,9 +46,9 @@ it('should print the correct context options for custom settings', async ({ runC
expect(cli.text()).toContain(expectedResult);
});
it('should print the correct context options when using a device', (test, { browserName }) => {
test('should print the correct context options when using a device', async ({ browserName, runCLI }) => {
test.skip(browserName !== 'chromium');
}, async ({ runCLI }) => {
const cli = runCLI(['--device=Pixel 2', '--target=java', emptyHTML]);
const expectedResult = `BrowserContext context = browser.newContext(new Browser.NewContextOptions()
.setUserAgent("Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36")
@ -62,9 +60,9 @@ it('should print the correct context options when using a device', (test, { brow
expect(cli.text()).toContain(expectedResult);
});
it('should print the correct context options when using a device and additional options', (test, { browserName }) => {
test('should print the correct context options when using a device and additional options', async ({ browserName, runCLI }) => {
test.skip(browserName !== 'webkit');
}, async ({ runCLI }) => {
const cli = runCLI(['--color-scheme=light', '--device=iPhone 11', '--target=java', emptyHTML]);
const expectedResult = `BrowserContext context = browser.newContext(new Browser.NewContextOptions()
.setColorScheme(ColorScheme.LIGHT)
@ -77,7 +75,7 @@ it('should print the correct context options when using a device and additional
expect(cli.text()).toContain(expectedResult);
});
it('should print load/save storage_state', async ({ runCLI, browserName, testInfo }) => {
test('should print load/save storage_state', async ({ runCLI, browserName }, testInfo) => {
const loadFileName = testInfo.outputPath('load.json');
const saveFileName = testInfo.outputPath('save.json');
await fs.promises.writeFile(loadFileName, JSON.stringify({ cookies: [], origins: [] }), 'utf8');

View file

@ -16,17 +16,15 @@
import fs from 'fs';
import path from 'path';
import { folio } from './cli.fixtures';
import { test, expect } from '../config/cliTest';
const { it, expect } = folio;
const emptyHTML = new URL('file://' + path.join(__dirname, '..', 'assets', 'empty.html')).toString();
const emptyHTML = new URL('file://' + path.join(__dirname, '..', '..', 'test', 'assets', 'empty.html')).toString();
const launchOptions = (channel: string) => {
return channel ? `headless: false,\n channel: '${channel}'` : 'headless: false';
};
it('should print the correct imports and context options', async ({ browserName, browserChannel, runCLI }) => {
test('should print the correct imports and context options', async ({ browserName, browserChannel, runCLI }) => {
const cli = runCLI([emptyHTML]);
const expectedResult = `const { ${browserName} } = require('playwright');
@ -39,7 +37,7 @@ it('should print the correct imports and context options', async ({ browserName,
expect(cli.text()).toContain(expectedResult);
});
it('should print the correct context options for custom settings', async ({ browserName, browserChannel, runCLI }) => {
test('should print the correct context options for custom settings', async ({ browserName, browserChannel, runCLI }) => {
const cli = runCLI(['--color-scheme=light', emptyHTML]);
const expectedResult = `const { ${browserName} } = require('playwright');
@ -55,9 +53,9 @@ it('should print the correct context options for custom settings', async ({ brow
});
it('should print the correct context options when using a device', (test, { browserName, browserChannel }) => {
test('should print the correct context options when using a device', async ({ browserName, browserChannel, runCLI }) => {
test.skip(browserName !== 'chromium');
}, async ({ browserChannel, runCLI }) => {
const cli = runCLI(['--device=Pixel 2', emptyHTML]);
const expectedResult = `const { chromium, devices } = require('playwright');
@ -72,9 +70,9 @@ it('should print the correct context options when using a device', (test, { brow
expect(cli.text()).toContain(expectedResult);
});
it('should print the correct context options when using a device and additional options', (test, { browserName }) => {
test('should print the correct context options when using a device and additional options', async ({ browserName, browserChannel, runCLI }) => {
test.skip(browserName !== 'webkit');
}, async ({ browserChannel, runCLI }) => {
const cli = runCLI(['--color-scheme=light', '--device=iPhone 11', emptyHTML]);
const expectedResult = `const { webkit, devices } = require('playwright');
@ -90,7 +88,7 @@ it('should print the correct context options when using a device and additional
expect(cli.text()).toContain(expectedResult);
});
it('should save the codegen output to a file if specified', async ({ browserName, browserChannel, runCLI, testInfo }) => {
test('should save the codegen output to a file if specified', async ({ browserName, browserChannel, runCLI }, testInfo) => {
const tmpFile = testInfo.outputPath('script.js');
const cli = runCLI(['--output', tmpFile, emptyHTML]);
await cli.exited;
@ -118,7 +116,7 @@ it('should save the codegen output to a file if specified', async ({ browserName
})();`);
});
it('should print load/save storageState', async ({ browserName, browserChannel, runCLI, testInfo }) => {
test('should print load/save storageState', async ({ browserName, browserChannel, runCLI }, testInfo) => {
const loadFileName = testInfo.outputPath('load.json');
const saveFileName = testInfo.outputPath('save.json');
await fs.promises.writeFile(loadFileName, JSON.stringify({ cookies: [], origins: [] }), 'utf8');

View file

@ -16,16 +16,14 @@
import fs from 'fs';
import path from 'path';
import { folio } from './cli.fixtures';
import { test, expect } from '../config/cliTest';
const { it, expect } = folio;
const emptyHTML = new URL('file://' + path.join(__dirname, '..', 'assets', 'empty.html')).toString();
const emptyHTML = new URL('file://' + path.join(__dirname, '..', '..', 'test', 'assets', 'empty.html')).toString();
const launchOptions = (channel: string) => {
return channel ? `headless=False, channel="${channel}"` : 'headless=False';
};
it('should print the correct imports and context options', async ({ browserName, browserChannel, runCLI }) => {
test('should print the correct imports and context options', async ({ browserName, browserChannel, runCLI }) => {
const cli = runCLI(['--target=python-async', emptyHTML]);
const expectedResult = `import asyncio
from playwright.async_api import async_playwright
@ -37,7 +35,7 @@ async def run(playwright):
expect(cli.text()).toContain(expectedResult);
});
it('should print the correct context options for custom settings', async ({ browserName, browserChannel, runCLI }) => {
test('should print the correct context options for custom settings', async ({ browserName, browserChannel, runCLI }) => {
const cli = runCLI(['--color-scheme=light', '--target=python-async', emptyHTML]);
const expectedResult = `import asyncio
from playwright.async_api import async_playwright
@ -49,9 +47,9 @@ async def run(playwright):
expect(cli.text()).toContain(expectedResult);
});
it('should print the correct context options when using a device', (test, { browserName }) => {
test('should print the correct context options when using a device', async ({ browserName, browserChannel, runCLI }) => {
test.skip(browserName !== 'chromium');
}, async ({ browserChannel, runCLI }) => {
const cli = runCLI(['--device=Pixel 2', '--target=python-async', emptyHTML]);
const expectedResult = `import asyncio
from playwright.async_api import async_playwright
@ -63,9 +61,9 @@ async def run(playwright):
expect(cli.text()).toContain(expectedResult);
});
it('should print the correct context options when using a device and additional options', (test, { browserName }) => {
test('should print the correct context options when using a device and additional options', async ({ browserName, browserChannel, runCLI }) => {
test.skip(browserName !== 'webkit');
}, async ({ browserChannel, runCLI }) => {
const cli = runCLI(['--color-scheme=light', '--device=iPhone 11', '--target=python-async', emptyHTML]);
const expectedResult = `import asyncio
from playwright.async_api import async_playwright
@ -77,7 +75,7 @@ async def run(playwright):
expect(cli.text()).toContain(expectedResult);
});
it('should save the codegen output to a file if specified', async ({ browserName, browserChannel, runCLI, testInfo }) => {
test('should save the codegen output to a file if specified', async ({ browserName, browserChannel, runCLI }, testInfo) => {
const tmpFile = testInfo.outputPath('script.js');
const cli = runCLI(['--target=python-async', '--output', tmpFile, emptyHTML]);
await cli.exited;
@ -108,7 +106,7 @@ async def main():
asyncio.run(main())`);
});
it('should print load/save storage_state', async ({ browserName, browserChannel, runCLI, testInfo }) => {
test('should print load/save storage_state', async ({ browserName, browserChannel, runCLI }, testInfo) => {
const loadFileName = testInfo.outputPath('load.json');
const saveFileName = testInfo.outputPath('save.json');
await fs.promises.writeFile(loadFileName, JSON.stringify({ cookies: [], origins: [] }), 'utf8');

View file

@ -16,16 +16,14 @@
import fs from 'fs';
import path from 'path';
import { folio } from './cli.fixtures';
import { test, expect } from '../config/cliTest';
const { it, expect } = folio;
const emptyHTML = new URL('file://' + path.join(__dirname, '..', 'assets', 'empty.html')).toString();
const emptyHTML = new URL('file://' + path.join(__dirname, '..', '..', 'test', 'assets', 'empty.html')).toString();
const launchOptions = (channel: string) => {
return channel ? `headless=False, channel="${channel}"` : 'headless=False';
};
it('should print the correct imports and context options', async ({ runCLI, browserChannel, browserName }) => {
test('should print the correct imports and context options', async ({ runCLI, browserChannel, browserName }) => {
const cli = runCLI(['--target=python', emptyHTML]);
const expectedResult = `from playwright.sync_api import sync_playwright
@ -36,7 +34,7 @@ def run(playwright):
expect(cli.text()).toContain(expectedResult);
});
it('should print the correct context options for custom settings', async ({ runCLI, browserChannel, browserName }) => {
test('should print the correct context options for custom settings', async ({ runCLI, browserChannel, browserName }) => {
const cli = runCLI(['--color-scheme=light', '--target=python', emptyHTML]);
const expectedResult = `from playwright.sync_api import sync_playwright
@ -47,9 +45,9 @@ def run(playwright):
expect(cli.text()).toContain(expectedResult);
});
it('should print the correct context options when using a device', (test, { browserName }) => {
test('should print the correct context options when using a device', async ({ browserName, browserChannel, runCLI }) => {
test.skip(browserName !== 'chromium');
}, async ({ browserChannel, runCLI }) => {
const cli = runCLI(['--device=Pixel 2', '--target=python', emptyHTML]);
const expectedResult = `from playwright.sync_api import sync_playwright
@ -60,9 +58,9 @@ def run(playwright):
expect(cli.text()).toContain(expectedResult);
});
it('should print the correct context options when using a device and additional options', (test, { browserName }) => {
test('should print the correct context options when using a device and additional options', async ({ browserName, browserChannel, runCLI }) => {
test.skip(browserName !== 'webkit');
}, async ({ browserChannel, runCLI }) => {
const cli = runCLI(['--color-scheme=light', '--device=iPhone 11', '--target=python', emptyHTML]);
const expectedResult = `from playwright.sync_api import sync_playwright
@ -73,7 +71,7 @@ def run(playwright):
expect(cli.text()).toContain(expectedResult);
});
it('should save the codegen output to a file if specified', async ({ runCLI, browserChannel, browserName, testInfo }) => {
test('should save the codegen output to a file if specified', async ({ runCLI, browserChannel, browserName }, testInfo) => {
const tmpFile = testInfo.outputPath('script.js');
const cli = runCLI(['--target=python', '--output', tmpFile, emptyHTML]);
await cli.exited;
@ -101,7 +99,7 @@ with sync_playwright() as playwright:
run(playwright)`);
});
it('should print load/save storage_state', async ({ runCLI, browserChannel, browserName, testInfo }) => {
test('should print load/save storage_state', async ({ runCLI, browserChannel, browserName }, testInfo) => {
const loadFileName = testInfo.outputPath('load.json');
const saveFileName = testInfo.outputPath('save.json');
await fs.promises.writeFile(loadFileName, JSON.stringify({ cookies: [], origins: [] }), 'utf8');

View file

@ -100,7 +100,7 @@ class DefaultMode {
export class PlaywrightEnv implements Env<PlaywrightTestArgs> {
private _mode: DriverMode | ServiceMode | DefaultMode;
private _browserName: BrowserName;
protected _browserName: BrowserName;
protected _options: LaunchOptions & TestOptions;
protected _browserOptions: LaunchOptions;
private _playwright: typeof import('../../index');
@ -200,6 +200,7 @@ export class PlaywrightEnv implements Env<PlaywrightTestArgs> {
}
async afterAll(workerInfo: WorkerInfo) {
await this._mode.teardown();
const { coverage, uninstall } = this._coverage!;
uninstall();
const coveragePath = path.join(__dirname, '..', '..', 'test', 'coverage-report', workerInfo.workerIndex + '.json');

74
tests/config/cliEnv.ts Normal file
View file

@ -0,0 +1,74 @@
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { Env, TestInfo, WorkerInfo } from '../folio/out';
import { PageEnv } from './browserEnv';
import { CLIMock, CLITestArgs, Recorder } from './cliTest';
import * as http from 'http';
import { recorderPageGetter } from '../../test/utils';
export class CLIEnv extends PageEnv implements Env<CLITestArgs> {
private _server: http.Server | undefined;
private _handler = (req: http.IncomingMessage, res: http.ServerResponse) => res.end();
private _port: number;
private _cli: CLIMock | undefined;
async beforeAll(workerInfo: WorkerInfo) {
await super.beforeAll(workerInfo);
this._port = 9907 + workerInfo.workerIndex;
this._server = http.createServer((req: http.IncomingMessage, res: http.ServerResponse) => this._handler(req, res)).listen(this._port);
}
private _runCLI(args: string[]) {
this._cli = new CLIMock(this._browserName, this._browserOptions.channel, !!this._browserOptions.headless, args);
return this._cli;
}
async beforeEach(testInfo: TestInfo) {
const result = await super.beforeEach(testInfo);
const { page, context, toImpl } = result;
return {
...result,
httpServer: {
setHandler: newHandler => this._handler = newHandler,
PREFIX: `http://127.0.0.1:${this._port}`,
},
runCLI: this._runCLI.bind(this),
openRecorder: async () => {
await (page.context() as any)._enableRecorder({ language: 'javascript', startRecording: true });
const recorderPage = await recorderPageGetter(context, toImpl);
return new Recorder(page, recorderPage);
},
};
}
async afterEach(testInfo: TestInfo) {
if (this._cli) {
await this._cli.exited;
this._cli = undefined;
}
await super.afterEach(testInfo);
}
async afterAll(workerInfo: WorkerInfo) {
if (this._server) {
this._server.close();
this._server = undefined;
}
await super.afterAll(workerInfo);
}
}

View file

@ -14,54 +14,31 @@
* limitations under the License.
*/
import { newTestType } from '../folio/out';
import type { Page } from '../../index';
import type { ServerTestArgs } from './serverTest';
import type { BrowserTestArgs } from './browserTest';
import * as http from 'http';
import path from 'path';
import { ChildProcess, spawn } from 'child_process';
import { folio as baseFolio } from '../fixtures';
import type { BrowserType, Browser, Page } from '../..';
export { config } from 'folio';
import * as path from 'path';
import type { Source } from '../../src/server/supplements/recorder/recorderTypes';
import { recorderPageGetter } from '../utils';
import { ChildProcess, spawn } from 'child_process';
export { expect } from 'folio';
type WorkerFixtures = {
browserType: BrowserType<Browser>;
browser: Browser;
httpServer: httpServer;
};
interface CLIHTTPServer {
setHandler: (handler: http.RequestListener) => void
PREFIX: string
}
type TestFixtures = {
recorder: Recorder;
export type CLITestArgs = BrowserTestArgs & {
page: Page;
httpServer: CLIHTTPServer;
openRecorder: () => Promise<Recorder>;
runCLI: (args: string[]) => CLIMock;
};
export const fixtures = baseFolio.extend<TestFixtures, WorkerFixtures>();
export const test = newTestType<CLITestArgs & ServerTestArgs>();
fixtures.recorder.init(async ({ page, context, toImpl }, runTest) => {
await (page.context() as any)._enableRecorder({ language: 'javascript', startRecording: true });
const recorderPage = await recorderPageGetter(context, toImpl);
await runTest(new Recorder(page, recorderPage));
});
fixtures.httpServer.init(async ({testWorkerIndex}, runTest) => {
let handler = (req: http.IncomingMessage, res: http.ServerResponse) => res.end();
const port = 9907 + testWorkerIndex;
const server = http.createServer((req: http.IncomingMessage, res: http.ServerResponse) => handler(req, res)).listen(port);
await runTest({
setHandler: newHandler => handler = newHandler,
PREFIX: `http://127.0.0.1:${port}`,
});
server.close();
}, { scope: 'worker' });
function removeAnsiColors(input: string): string {
const pattern = [
'[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)',
'(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))'
].join('|');
return input.replace(new RegExp(pattern, 'g'), '');
}
class Recorder {
export class Recorder {
page: Page;
_highlightCallback: Function
_highlightInstalled: boolean
@ -150,17 +127,7 @@ class Recorder {
}
}
fixtures.runCLI.init(async ({ browserName, browserChannel, headful }, runTest) => {
let cli: CLIMock;
const cliFactory = (args: string[]) => {
cli = new CLIMock(browserName, browserChannel, !headful, args);
return cli;
};
await runTest(cliFactory);
await cli.exited;
});
class CLIMock {
export class CLIMock {
private process: ChildProcess;
private data: string;
private waitForText: string;
@ -210,9 +177,10 @@ class CLIMock {
}
}
interface httpServer {
setHandler: (handler: http.RequestListener) => void
PREFIX: string
function removeAnsiColors(input: string): string {
const pattern = [
'[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)',
'(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))'
].join('|');
return input.replace(new RegExp(pattern, 'g'), '');
}
export const folio = fixtures.build();

View file

@ -20,9 +20,11 @@ import { test as playwrightTest, slowTest as playwrightSlowTest } from './playwr
import { test as browserTest } from './browserTest';
import { test as pageTest } from './pageTest';
import { test as electronTest } from './electronTest';
import { test as cliTest } from './cliTest';
import { PlaywrightEnv, BrowserEnv, PageEnv, BrowserName } from './browserEnv';
import { ServerEnv } from './serverEnv';
import { ElectronEnv } from './electronEnv';
import { CLIEnv } from './cliEnv';
const config: Config = {
testDir: path.join(__dirname, '..'),
@ -63,6 +65,7 @@ for (const browserName of browsers) {
playwrightSlowTest.runWith(browserName, serverEnv, new PlaywrightEnv(browserName, options), { timeout: config.timeout * 3 });
browserTest.runWith(browserName, serverEnv, new BrowserEnv(browserName, options), {});
pageTest.runWith(browserName, serverEnv, new PageEnv(browserName, options), {});
cliTest.runWith(browserName, serverEnv, new CLIEnv(browserName, options), {});
if (browserName === 'chromium')
electronTest.runWith(browserName, serverEnv, new ElectronEnv({ mode }));
}

View file

@ -136,15 +136,14 @@ export function newTestTypeImpl(): any {
function hook(name: string, fn: Function) {
if (!currentFile)
throw errorWithCallLocation(`Hook can only be defined in a test file.`);
ensureSuiteForCurrentLocation();
suites[0]._addHook(name, fn);
}
const modifier = (type: 'skip' | 'fail' | 'fixme', arg?: boolean | string, description?: string) => {
const processed = interpretCondition(arg, description);
if (!processed.condition)
return;
if (currentFile) {
const processed = interpretCondition(arg, description);
if (processed.condition)
suites[0]._annotations.push({ type, description: processed.description });
return;
}
@ -152,15 +151,7 @@ export function newTestTypeImpl(): any {
const testInfo = currentTestInfo();
if (!testInfo)
throw new Error(`test.${type} can only be called inside the test`);
testInfo.annotations.push({ type, description: processed.description });
if (type === 'skip' || type === 'fixme') {
testInfo.expectedStatus = 'skipped';
throw new SkipError(processed.description);
} else if (type === 'fail') {
if (testInfo.expectedStatus !== 'skipped')
testInfo.expectedStatus = 'failed';
}
(testInfo[type] as any)(arg, description);
};
const test: any = spec.bind(null, 'default');
@ -197,9 +188,6 @@ export function newTestTypeImpl(): any {
return test;
}
export class SkipError extends Error {
}
export function setConfig(config: Config) {
// TODO: add config validation.
configFile.config = config;

View file

@ -40,6 +40,23 @@ export interface Config extends RunWithConfig {
}
export type FullConfig = Required<Config>;
interface TestModifier {
skip(): void;
skip(condition: boolean): void;
skip(description: string): void;
skip(condition: boolean, description: string): void;
fixme(): void;
fixme(condition: boolean): void;
fixme(description: string): void;
fixme(condition: boolean, description: string): void;
fail(): void;
fail(condition: boolean): void;
fail(description: string): void;
fail(condition: boolean, description: string): void;
}
export type TestStatus = 'passed' | 'failed' | 'timedOut' | 'skipped';
export interface WorkerInfo {
@ -48,7 +65,7 @@ export interface WorkerInfo {
globalSetupResult: any;
}
export interface TestInfo extends WorkerInfo {
export interface TestInfo extends WorkerInfo, TestModifier {
// Declaration
title: string;
file: string;
@ -87,7 +104,7 @@ interface TestFunction<TestArgs, TestOptions> {
(name: string, options: TestOptions, fn: (args: TestArgs, testInfo: TestInfo) => any): void;
}
export interface TestType<TestArgs, TestOptions> extends TestFunction<TestArgs, TestOptions> {
export interface TestType<TestArgs, TestOptions> extends TestFunction<TestArgs, TestOptions>, TestModifier {
only: TestFunction<TestArgs, TestOptions>;
describe: SuiteFunction & {
only: SuiteFunction;
@ -100,21 +117,6 @@ export interface TestType<TestArgs, TestOptions> extends TestFunction<TestArgs,
expect: Expect;
skip(): void;
skip(condition: boolean): void;
skip(description: string): void;
skip(condition: boolean, description: string): void;
fixme(): void;
fixme(condition: boolean): void;
fixme(description: string): void;
fixme(condition: boolean, description: string): void;
fail(): void;
fail(condition: boolean): void;
fail(description: string): void;
fail(condition: boolean, description: string): void;
runWith(config?: RunWithConfig): void;
runWith(alias: string, config?: RunWithConfig): void;
runWith(env: Env<TestArgs>, config?: RunWithConfig): void;

View file

@ -17,13 +17,13 @@
import fs from 'fs';
import path from 'path';
import { EventEmitter } from 'events';
import { monotonicTime, raceAgainstDeadline, serializeError } from './util';
import { interpretCondition, monotonicTime, raceAgainstDeadline, serializeError } from './util';
import { TestBeginPayload, TestEndPayload, RunPayload, TestEntry, DonePayload, WorkerInitParams } from './ipc';
import { setCurrentTestInfo } from './globals';
import { Loader } from './loader';
import { Spec, Suite, Test } from './test';
import { TestInfo, WorkerInfo } from './types';
import { SkipError, RunListDescription } from './spec';
import { RunListDescription } from './spec';
export class WorkerRunner extends EventEmitter {
private _params: WorkerInitParams;
@ -230,6 +230,9 @@ export class WorkerRunner extends EventEmitter {
return path.join(basePath, ...pathSegments);
},
testOptions: spec.testOptions,
skip: (arg?: boolean | string, description?: string) => modifier(testInfo, 'skip', arg, description),
fixme: (arg?: boolean | string, description?: string) => modifier(testInfo, 'fixme', arg, description),
fail: (arg?: boolean | string, description?: string) => modifier(testInfo, 'fail', arg, description),
};
this._setCurrentTestInfo(testInfo);
@ -438,3 +441,20 @@ function buildTestEndPayload(testId: string, testInfo: TestInfo): TestEndPayload
timeout: testInfo.timeout,
};
}
function modifier(testInfo: TestInfo, type: 'skip' | 'fail' | 'fixme', arg?: boolean | string, description?: string) {
const processed = interpretCondition(arg, description);
if (!processed.condition)
return;
testInfo.annotations.push({ type, description: processed.description });
if (type === 'skip' || type === 'fixme') {
testInfo.expectedStatus = 'skipped';
throw new SkipError(processed.description);
} else if (type === 'fail') {
if (testInfo.expectedStatus !== 'skipped')
testInfo.expectedStatus = 'failed';
}
}
class SkipError extends Error {
}

View file

@ -29,9 +29,12 @@ test('should close the browser when the node process closes', async ({startRemot
expect(await remoteServer.childExitCode()).toBe(isWindows ? 1 : 0);
});
test('should report browser close signal', async ({startRemoteServer, server, platform, headful}) => {
test.describe('signals', () => {
test.beforeEach(async ({platform, headful}) => {
test.skip(platform === 'win32' || headful);
});
test('should report browser close signal', async ({startRemoteServer, server}) => {
const remoteServer = await startRemoteServer({ url: server.EMPTY_PAGE });
const pid = await remoteServer.out('pid');
process.kill(-pid, 'SIGTERM');
@ -39,11 +42,9 @@ test('should report browser close signal', async ({startRemoteServer, server, pl
expect(await remoteServer.out('signal')).toBe('SIGTERM');
process.kill(remoteServer.child().pid);
await remoteServer.childExitCode();
});
test('should report browser close signal 2', async ({startRemoteServer, server, platform, headful}) => {
test.skip(platform === 'win32' || headful);
});
test('should report browser close signal 2', async ({startRemoteServer, server}) => {
const remoteServer = await startRemoteServer({ url: server.EMPTY_PAGE });
const pid = await remoteServer.out('pid');
process.kill(-pid, 'SIGKILL');
@ -51,10 +52,9 @@ test('should report browser close signal 2', async ({startRemoteServer, server,
expect(await remoteServer.out('signal')).toBe('SIGKILL');
process.kill(remoteServer.child().pid);
await remoteServer.childExitCode();
});
});
test('should close the browser on SIGINT', async ({startRemoteServer, server, browserChannel, platform, headful}) => {
test.skip(platform === 'win32' || headful);
test('should close the browser on SIGINT', async ({startRemoteServer, server, browserChannel}) => {
test.fixme(!!browserChannel, 'Uncomment on roll');
const remoteServer = await startRemoteServer({ url: server.EMPTY_PAGE });
@ -62,10 +62,9 @@ test('should close the browser on SIGINT', async ({startRemoteServer, server, br
expect(await remoteServer.out('exitCode')).toBe('0');
expect(await remoteServer.out('signal')).toBe('null');
expect(await remoteServer.childExitCode()).toBe(130);
});
});
test('should close the browser on SIGTERM', async ({startRemoteServer, server, browserChannel, platform, headful}) => {
test.skip(platform === 'win32' || headful);
test('should close the browser on SIGTERM', async ({startRemoteServer, server, browserChannel}) => {
test.fixme(!!browserChannel, 'Uncomment on roll');
const remoteServer = await startRemoteServer({ url: server.EMPTY_PAGE });
@ -73,10 +72,9 @@ test('should close the browser on SIGTERM', async ({startRemoteServer, server, b
expect(await remoteServer.out('exitCode')).toBe('0');
expect(await remoteServer.out('signal')).toBe('null');
expect(await remoteServer.childExitCode()).toBe(0);
});
});
test('should close the browser on SIGHUP', async ({startRemoteServer, server, browserChannel, platform, headful}) => {
test.skip(platform === 'win32' || headful);
test('should close the browser on SIGHUP', async ({startRemoteServer, server, browserChannel}) => {
test.fixme(!!browserChannel, 'Uncomment on roll');
const remoteServer = await startRemoteServer({ url: server.EMPTY_PAGE });
@ -84,11 +82,9 @@ test('should close the browser on SIGHUP', async ({startRemoteServer, server, br
expect(await remoteServer.out('exitCode')).toBe('0');
expect(await remoteServer.out('signal')).toBe('null');
expect(await remoteServer.childExitCode()).toBe(0);
});
test('should kill the browser on double SIGINT', async ({startRemoteServer, server, platform, headful}) => {
test.skip(platform === 'win32' || headful);
});
test('should kill the browser on double SIGINT', async ({startRemoteServer, server}) => {
const remoteServer = await startRemoteServer({ stallOnClose: true, url: server.EMPTY_PAGE });
process.kill(remoteServer.child().pid, 'SIGINT');
await remoteServer.out('stalled');
@ -96,11 +92,9 @@ test('should kill the browser on double SIGINT', async ({startRemoteServer, serv
expect(await remoteServer.out('exitCode')).toBe('null');
expect(await remoteServer.out('signal')).toBe('SIGKILL');
expect(await remoteServer.childExitCode()).toBe(130);
});
test('should kill the browser on SIGINT + SIGTERM', async ({startRemoteServer, server, platform, headful}) => {
test.skip(platform === 'win32' || headful);
});
test('should kill the browser on SIGINT + SIGTERM', async ({startRemoteServer, server}) => {
const remoteServer = await startRemoteServer({ stallOnClose: true, url: server.EMPTY_PAGE });
process.kill(remoteServer.child().pid, 'SIGINT');
await remoteServer.out('stalled');
@ -108,11 +102,9 @@ test('should kill the browser on SIGINT + SIGTERM', async ({startRemoteServer, s
expect(await remoteServer.out('exitCode')).toBe('null');
expect(await remoteServer.out('signal')).toBe('SIGKILL');
expect(await remoteServer.childExitCode()).toBe(0);
});
test('should kill the browser on SIGTERM + SIGINT', async ({startRemoteServer, server, platform, headful}) => {
test.skip(platform === 'win32' || headful);
});
test('should kill the browser on SIGTERM + SIGINT', async ({startRemoteServer, server}) => {
const remoteServer = await startRemoteServer({ stallOnClose: true, url: server.EMPTY_PAGE });
process.kill(remoteServer.child().pid, 'SIGTERM');
await remoteServer.out('stalled');
@ -120,4 +112,5 @@ test('should kill the browser on SIGTERM + SIGINT', async ({startRemoteServer, s
expect(await remoteServer.out('exitCode')).toBe('null');
expect(await remoteServer.out('signal')).toBe('SIGKILL');
expect(await remoteServer.childExitCode()).toBe(130);
});
});