fix: fix the cli tests, generate snake python (#5003)
This commit is contained in:
parent
decf373c81
commit
9a9ac60d21
|
|
@ -341,7 +341,7 @@ async function codegen(options: Options, url: string | undefined, target: string
|
|||
if (process.env.PWTRACE)
|
||||
contextOptions.recordVideo = { dir: path.join(process.cwd(), '.trace') };
|
||||
|
||||
const outputs: CodeGeneratorOutput[] = [new TerminalOutput(process.stdout, languageGenerator.highligherType())];
|
||||
const outputs: CodeGeneratorOutput[] = [TerminalOutput.create(process.stdout, languageGenerator.highlighterType())];
|
||||
if (outputFile)
|
||||
outputs.push(new FileOutput(outputFile));
|
||||
const output = new OutputMultiplexer(outputs);
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import { MouseClickOptions, toModifiers } from '../utils';
|
|||
|
||||
export class CSharpLanguageGenerator implements LanguageGenerator {
|
||||
|
||||
highligherType(): HighlighterType {
|
||||
highlighterType(): HighlighterType {
|
||||
return 'csharp';
|
||||
}
|
||||
|
||||
|
|
@ -155,7 +155,7 @@ export class CSharpLanguageGenerator implements LanguageGenerator {
|
|||
}
|
||||
|
||||
generateFooter(saveStorage: string | undefined): string {
|
||||
const storageStateLine = saveStorage ? `\nawait context.StorageStateAsync(path: "${saveStorage}")` : '';
|
||||
const storageStateLine = saveStorage ? `\nawait context.StorageStateAsync(path: "${saveStorage}");` : '';
|
||||
return `// ---------------------${storageStateLine}`;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ export interface LanguageGenerator {
|
|||
generateHeader(browserName: string, launchOptions: LaunchOptions, contextOptions: BrowserContextOptions, deviceName?: string): string;
|
||||
generateAction(actionInContext: ActionInContext, performingAction: boolean): string;
|
||||
generateFooter(saveStorage: string | undefined): string;
|
||||
highligherType(): HighlighterType;
|
||||
highlighterType(): HighlighterType;
|
||||
}
|
||||
|
||||
export { JavaScriptLanguageGenerator } from './javascript';
|
||||
|
|
@ -23,7 +23,7 @@ import { MouseClickOptions, toModifiers } from '../utils';
|
|||
|
||||
export class JavaScriptLanguageGenerator implements LanguageGenerator {
|
||||
|
||||
highligherType(): HighlighterType {
|
||||
highlighterType(): HighlighterType {
|
||||
return 'javascript';
|
||||
}
|
||||
|
||||
|
|
@ -157,7 +157,7 @@ export class JavaScriptLanguageGenerator implements LanguageGenerator {
|
|||
}
|
||||
|
||||
generateFooter(saveStorage: string | undefined): string {
|
||||
const storageStateLine = saveStorage ? `\n await context.storageState({ path: '${saveStorage}' })` : '';
|
||||
const storageStateLine = saveStorage ? `\n await context.storageState({ path: '${saveStorage}' });` : '';
|
||||
return ` // ---------------------${storageStateLine}
|
||||
await context.close();
|
||||
await browser.close();
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ export class PythonLanguageGenerator implements LanguageGenerator {
|
|||
this._asyncPrefix = isAsync ? 'async ' : '';
|
||||
}
|
||||
|
||||
highligherType(): HighlighterType {
|
||||
highlighterType(): HighlighterType {
|
||||
return 'python';
|
||||
}
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ export class PythonLanguageGenerator implements LanguageGenerator {
|
|||
formatter.add('# ' + actionTitle(action));
|
||||
|
||||
if (action.name === 'openPage') {
|
||||
formatter.add(`${pageAlias} = ${this._awaitPrefix}context.newPage()`);
|
||||
formatter.add(`${pageAlias} = ${this._awaitPrefix}context.new_page()`);
|
||||
if (action.url && action.url !== 'about:blank' && action.url !== 'chrome://newtab/')
|
||||
formatter.add(`${pageAlias}.goto('${action.url}')`);
|
||||
return formatter.format();
|
||||
|
|
@ -155,21 +155,21 @@ from playwright.async_api import async_playwright
|
|||
|
||||
async def run(playwright) {
|
||||
browser = await playwright.${browserName}.launch(${formatOptions(launchOptions, false)})
|
||||
context = await browser.newContext(${formatContextOptions(contextOptions, deviceName)})`);
|
||||
context = await browser.new_context(${formatContextOptions(contextOptions, deviceName)})`);
|
||||
} else {
|
||||
formatter.add(`
|
||||
from playwright.sync_api import sync_playwright
|
||||
|
||||
def run(playwright) {
|
||||
browser = playwright.${browserName}.launch(${formatOptions(launchOptions, false)})
|
||||
context = browser.newContext(${formatContextOptions(contextOptions, deviceName)})`);
|
||||
context = browser.new_context(${formatContextOptions(contextOptions, deviceName)})`);
|
||||
}
|
||||
return formatter.format();
|
||||
}
|
||||
|
||||
generateFooter(saveStorage: string | undefined): string {
|
||||
if (this._isAsync) {
|
||||
const storageStateLine = saveStorage ? `\n await context.storageState(path="${saveStorage}")` : '';
|
||||
const storageStateLine = saveStorage ? `\n await context.storage_state(path="${saveStorage}")` : '';
|
||||
return ` # ---------------------${storageStateLine}
|
||||
await context.close()
|
||||
await browser.close()
|
||||
|
|
@ -179,7 +179,7 @@ async def main():
|
|||
await run(playwright)
|
||||
asyncio.run(main())`;
|
||||
} else {
|
||||
const storageStateLine = saveStorage ? `\n context.storageState(path="${saveStorage}")` : '';
|
||||
const storageStateLine = saveStorage ? `\n context.storage_state(path="${saveStorage}")` : '';
|
||||
return ` # ---------------------${storageStateLine}
|
||||
context.close()
|
||||
browser.close()
|
||||
|
|
@ -204,11 +204,16 @@ function formatValue(value: any): string {
|
|||
return String(value);
|
||||
}
|
||||
|
||||
function toSnakeCase(name: string): string {
|
||||
const toSnakeCaseRegex = /((?<=[a-z0-9])[A-Z]|(?!^)[A-Z](?=[a-z]))/g;
|
||||
return name.replace(toSnakeCaseRegex, `_$1`).toLowerCase();
|
||||
}
|
||||
|
||||
function formatOptions(value: any, hasArguments: boolean): string {
|
||||
const keys = Object.keys(value);
|
||||
if (!keys.length)
|
||||
return '';
|
||||
return (hasArguments ? ', ' : '') + keys.map(key => `${key}=${formatValue(value[key])}`).join(', ');
|
||||
return (hasArguments ? ', ' : '') + keys.map(key => `${toSnakeCase(key)}=${formatValue(value[key])}`).join(', ');
|
||||
}
|
||||
|
||||
function formatContextOptions(options: BrowserContextOptions, deviceName: string | undefined): string {
|
||||
|
|
|
|||
|
|
@ -42,24 +42,32 @@ export class OutputMultiplexer implements CodeGeneratorOutput {
|
|||
}
|
||||
}
|
||||
|
||||
export class FileOutput implements CodeGeneratorOutput {
|
||||
private _fileName: string;
|
||||
private _lines: string[];
|
||||
constructor(fileName: string) {
|
||||
this._fileName = fileName;
|
||||
this._lines = [];
|
||||
}
|
||||
export class BufferOutput {
|
||||
lines: string[] = [];
|
||||
|
||||
printLn(text: string) {
|
||||
this._lines.push(...text.trimEnd().split('\n'));
|
||||
this.lines.push(...text.trimEnd().split('\n'));
|
||||
}
|
||||
|
||||
popLn(text: string) {
|
||||
this._lines.length -= text.trimEnd().split('\n').length;
|
||||
this.lines.length -= text.trimEnd().split('\n').length;
|
||||
}
|
||||
|
||||
buffer(): string {
|
||||
return this.lines.join('\n');
|
||||
}
|
||||
}
|
||||
|
||||
export class FileOutput extends BufferOutput implements CodeGeneratorOutput {
|
||||
private _fileName: string;
|
||||
|
||||
constructor(fileName: string) {
|
||||
super();
|
||||
this._fileName = fileName;
|
||||
}
|
||||
|
||||
flush() {
|
||||
fs.writeFileSync(this._fileName, this._lines.join('\n'));
|
||||
fs.writeFileSync(this._fileName, this.buffer());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -67,6 +75,12 @@ export class TerminalOutput implements CodeGeneratorOutput {
|
|||
private _output: Writable
|
||||
private _language: string;
|
||||
|
||||
static create(output: Writable, language: string) {
|
||||
if (process.stdout.columns)
|
||||
return new TerminalOutput(output, language);
|
||||
return new FlushingTerminalOutput(output);
|
||||
}
|
||||
|
||||
constructor(output: Writable, language: string) {
|
||||
this._output = output;
|
||||
this._language = language;
|
||||
|
|
@ -112,3 +126,23 @@ export class TerminalOutput implements CodeGeneratorOutput {
|
|||
|
||||
flush() {}
|
||||
}
|
||||
|
||||
export class FlushingTerminalOutput extends BufferOutput implements CodeGeneratorOutput {
|
||||
private _output: Writable
|
||||
|
||||
constructor(output: Writable) {
|
||||
super();
|
||||
this._output = output;
|
||||
}
|
||||
|
||||
printLn(text: string) {
|
||||
super.printLn(text);
|
||||
this._output.write('-------------8<-------------\n');
|
||||
this._output.write(this.buffer() + '\n');
|
||||
this._output.write('-------------8<-------------\n');
|
||||
}
|
||||
|
||||
flush() {
|
||||
this._output.write(this.buffer() + '\n');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ it('should print load/save storageState', async ({ runCLI, testInfo }) => {
|
|||
const cli = runCLI([`--load-storage=${loadFileName}`, `--save-storage=${saveFileName}`, 'codegen', '--target=csharp', emptyHTML]);
|
||||
const expectedResult = `await Playwright.InstallAsync();
|
||||
using var playwright = await Playwright.CreateAsync();
|
||||
await using var browser = await playwright.Chromium.LaunchAsync();
|
||||
await using var browser = await playwright.Chromium.LaunchAsync(headless: false);
|
||||
var context = await browser.NewContextAsync(storageState: "${loadFileName}");
|
||||
|
||||
// Open new page
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ it('should save the codegen output to a file if specified', async ({ runCLI, tes
|
|||
const tmpFile = testInfo.outputPath('script.js');
|
||||
const cli = runCLI(['codegen', '--output', tmpFile, emptyHTML]);
|
||||
await cli.exited;
|
||||
const content = await fs.readFileSync(tmpFile);
|
||||
const content = fs.readFileSync(tmpFile);
|
||||
expect(content.toString()).toBe(`const { chromium } = require('playwright');
|
||||
|
||||
(async () => {
|
||||
|
|
@ -115,7 +115,7 @@ it('should print load/save storageState', async ({ runCLI, testInfo }) => {
|
|||
const saveFileName = testInfo.outputPath('save.json');
|
||||
await fs.promises.writeFile(loadFileName, JSON.stringify({ cookies: [], origins: [] }), 'utf8');
|
||||
const cli = runCLI([`--load-storage=${loadFileName}`, `--save-storage=${saveFileName}`, 'codegen', emptyHTML]);
|
||||
const expectedResult = `const { chromium, devices } = require('playwright');
|
||||
const expectedResult = `const { chromium } = require('playwright');
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ from playwright.async_api import async_playwright
|
|||
|
||||
async def run(playwright):
|
||||
browser = await playwright.chromium.launch(headless=False)
|
||||
context = await browser.newContext()`;
|
||||
context = await browser.new_context()`;
|
||||
await cli.waitFor(expectedResult);
|
||||
expect(cli.text()).toContain(expectedResult);
|
||||
});
|
||||
|
|
@ -41,7 +41,7 @@ from playwright.async_api import async_playwright
|
|||
|
||||
async def run(playwright):
|
||||
browser = await playwright.chromium.launch(headless=False)
|
||||
context = await browser.newContext(colorScheme="light")`;
|
||||
context = await browser.new_context(color_scheme="light")`;
|
||||
await cli.waitFor(expectedResult);
|
||||
expect(cli.text()).toContain(expectedResult);
|
||||
});
|
||||
|
|
@ -53,7 +53,7 @@ from playwright.async_api import async_playwright
|
|||
|
||||
async def run(playwright):
|
||||
browser = await playwright.chromium.launch(headless=False)
|
||||
context = await browser.newContext(**playwright.devices["Pixel 2"])`;
|
||||
context = await browser.new_context(**playwright.devices["Pixel 2"])`;
|
||||
await cli.waitFor(expectedResult);
|
||||
expect(cli.text()).toContain(expectedResult);
|
||||
});
|
||||
|
|
@ -65,7 +65,7 @@ from playwright.async_api import async_playwright
|
|||
|
||||
async def run(playwright):
|
||||
browser = await playwright.chromium.launch(headless=False)
|
||||
context = await browser.newContext(**playwright.devices["Pixel 2"], colorScheme="light")`;
|
||||
context = await browser.new_context(**playwright.devices["Pixel 2"], color_scheme="light")`;
|
||||
await cli.waitFor(expectedResult);
|
||||
expect(cli.text()).toContain(expectedResult);
|
||||
});
|
||||
|
|
@ -80,10 +80,10 @@ from playwright.async_api import async_playwright
|
|||
|
||||
async def run(playwright):
|
||||
browser = await playwright.chromium.launch(headless=False)
|
||||
context = await browser.newContext()
|
||||
context = await browser.new_context()
|
||||
|
||||
# Open new page
|
||||
page = await context.newPage()
|
||||
page = await context.new_page()
|
||||
|
||||
# Go to ${emptyHTML}
|
||||
await page.goto("${emptyHTML}")
|
||||
|
|
@ -101,29 +101,29 @@ async def main():
|
|||
asyncio.run(main())`);
|
||||
});
|
||||
|
||||
it('should print load/save storageState', async ({ runCLI, testInfo }) => {
|
||||
it('should print load/save storage_state', async ({ runCLI, testInfo }) => {
|
||||
const loadFileName = testInfo.outputPath('load.json');
|
||||
const saveFileName = testInfo.outputPath('save.json');
|
||||
await fs.promises.writeFile(loadFileName, JSON.stringify({ cookies: [], origins: [] }), 'utf8');
|
||||
const cli = runCLI([`--load-storage=${loadFileName}`, `--save-storage=${saveFileName}`, 'codegen', '--target=python-async', emptyHTML]);
|
||||
const expectedResult = `import asyncio
|
||||
from playwright.async_api import async_playwright
|
||||
from playwright.async_api import async_playwright
|
||||
|
||||
async def run(playwright):
|
||||
browser = await playwright.chromium.launch(headless=False)
|
||||
context = await browser.newContext(storageState="${loadFileName}")
|
||||
async def run(playwright):
|
||||
browser = await playwright.chromium.launch(headless=False)
|
||||
context = await browser.new_context(storage_state="${loadFileName}")
|
||||
|
||||
# Open new page
|
||||
page = await context.newPage()
|
||||
# Open new page
|
||||
page = await context.new_page()
|
||||
|
||||
# ---------------------
|
||||
await context.storageState(path="${saveFileName}")
|
||||
await context.close()
|
||||
await browser.close()
|
||||
# ---------------------
|
||||
await context.storage_state(path="${saveFileName}")
|
||||
await context.close()
|
||||
await browser.close()
|
||||
|
||||
async def main():
|
||||
async with async_playwright() as playwright:
|
||||
await run(playwright)
|
||||
asyncio.run(main())`;
|
||||
async def main():
|
||||
async with async_playwright() as playwright:
|
||||
await run(playwright)
|
||||
asyncio.run(main())`;
|
||||
await cli.waitFor(expectedResult);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ it('should print the correct imports and context options', async ({ runCLI }) =>
|
|||
|
||||
def run(playwright):
|
||||
browser = playwright.chromium.launch(headless=False)
|
||||
context = browser.newContext()`;
|
||||
context = browser.new_context()`;
|
||||
await cli.waitFor(expectedResult);
|
||||
expect(cli.text()).toContain(expectedResult);
|
||||
});
|
||||
|
|
@ -39,7 +39,7 @@ it('should print the correct context options for custom settings', async ({ runC
|
|||
|
||||
def run(playwright):
|
||||
browser = playwright.chromium.launch(headless=False)
|
||||
context = browser.newContext(colorScheme="light")`;
|
||||
context = browser.new_context(color_scheme="light")`;
|
||||
await cli.waitFor(expectedResult);
|
||||
expect(cli.text()).toContain(expectedResult);
|
||||
});
|
||||
|
|
@ -50,7 +50,7 @@ it('should print the correct context options when using a device', async ({ runC
|
|||
|
||||
def run(playwright):
|
||||
browser = playwright.chromium.launch(headless=False)
|
||||
context = browser.newContext(**playwright.devices["Pixel 2"])`;
|
||||
context = browser.new_context(**playwright.devices["Pixel 2"])`;
|
||||
await cli.waitFor(expectedResult);
|
||||
expect(cli.text()).toContain(expectedResult);
|
||||
});
|
||||
|
|
@ -61,7 +61,7 @@ it('should print the correct context options when using a device and additional
|
|||
|
||||
def run(playwright):
|
||||
browser = playwright.chromium.launch(headless=False)
|
||||
context = browser.newContext(**playwright.devices["Pixel 2"], colorScheme="light")`;
|
||||
context = browser.new_context(**playwright.devices["Pixel 2"], color_scheme="light")`;
|
||||
await cli.waitFor(expectedResult);
|
||||
expect(cli.text()).toContain(expectedResult);
|
||||
});
|
||||
|
|
@ -75,10 +75,10 @@ it('should save the codegen output to a file if specified', async ({ runCLI, tes
|
|||
|
||||
def run(playwright):
|
||||
browser = playwright.chromium.launch(headless=False)
|
||||
context = browser.newContext()
|
||||
context = browser.new_context()
|
||||
|
||||
# Open new page
|
||||
page = context.newPage()
|
||||
page = context.new_page()
|
||||
|
||||
# Go to ${emptyHTML}
|
||||
page.goto("${emptyHTML}")
|
||||
|
|
@ -94,26 +94,26 @@ with sync_playwright() as playwright:
|
|||
run(playwright)`);
|
||||
});
|
||||
|
||||
it('should print load/save storageState', async ({ runCLI, testInfo }) => {
|
||||
it('should print load/save storage_state', async ({ runCLI, testInfo }) => {
|
||||
const loadFileName = testInfo.outputPath('load.json');
|
||||
const saveFileName = testInfo.outputPath('save.json');
|
||||
await fs.promises.writeFile(loadFileName, JSON.stringify({ cookies: [], origins: [] }), 'utf8');
|
||||
const cli = runCLI([`--load-storage=${loadFileName}`, `--save-storage=${saveFileName}`, 'codegen', '--target=python', emptyHTML]);
|
||||
const expectedResult = `from playwright.sync_api import sync_playwright
|
||||
|
||||
def run(playwright):
|
||||
browser = playwright.chromium.launch(headless=False)
|
||||
context = browser.newContext(storageState="${loadFileName}")
|
||||
def run(playwright):
|
||||
browser = playwright.chromium.launch(headless=False)
|
||||
context = browser.new_context(storage_state="${loadFileName}")
|
||||
|
||||
# Open new page
|
||||
page = context.newPage()
|
||||
# Open new page
|
||||
page = context.new_page()
|
||||
|
||||
# ---------------------
|
||||
context.storageState(path="${saveFileName}")
|
||||
context.close()
|
||||
browser.close()
|
||||
# ---------------------
|
||||
context.storage_state(path="${saveFileName}")
|
||||
context.close()
|
||||
browser.close()
|
||||
|
||||
with sync_playwright() as playwright:
|
||||
run(playwright)`;
|
||||
with sync_playwright() as playwright:
|
||||
run(playwright)`;
|
||||
await cli.waitFor(expectedResult);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ fixtures.runCLI.init(async ({ }, runTest) => {
|
|||
return cli;
|
||||
};
|
||||
await runTest(cliFactory);
|
||||
cli.kill();
|
||||
await cli.exited;
|
||||
});
|
||||
|
||||
class CLIMock {
|
||||
|
|
@ -216,18 +216,20 @@ class CLIMock {
|
|||
env: {
|
||||
...process.env,
|
||||
PWCLI_EXIT_FOR_TEST: '1'
|
||||
}
|
||||
},
|
||||
stdio: 'pipe'
|
||||
});
|
||||
this.process.stdout.on('data', line => {
|
||||
this.data += removeAnsiColors(line.toString());
|
||||
this.process.stdout.on('data', data => {
|
||||
this.data = data.toString();
|
||||
if (this.waitForCallback && this.data.includes(this.waitForText))
|
||||
this.waitForCallback();
|
||||
});
|
||||
this.exited = new Promise<void>(r => this.process.on('exit', () => {
|
||||
if (this.waitForCallback)
|
||||
this.waitForCallback();
|
||||
return r();
|
||||
}));
|
||||
this.exited = new Promise((f, r) => {
|
||||
this.process.stderr.on('data', data => {
|
||||
r(new Error(data));
|
||||
});
|
||||
this.process.on('exit', f);
|
||||
});
|
||||
}
|
||||
|
||||
async waitFor(text: string): Promise<void> {
|
||||
|
|
@ -240,10 +242,6 @@ class CLIMock {
|
|||
text() {
|
||||
return removeAnsiColors(this.data);
|
||||
}
|
||||
|
||||
kill() {
|
||||
this.process.kill();
|
||||
}
|
||||
}
|
||||
|
||||
interface httpServer {
|
||||
|
|
|
|||
Loading…
Reference in a new issue