Files
AI/참고/playwright-main/tests/mcp/cli-core.spec.ts
2026-05-12 19:40:31 +09:00

371 lines
15 KiB
TypeScript

/**
* 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 fs from 'fs';
import path from 'path';
import { test, expect, eventsPage } from './cli-fixtures';
test('open', async ({ cli, server }) => {
const { output, snapshot } = await cli('open', server.HELLO_WORLD);
expect(output).toContain(`### Page
- Page URL: ${server.HELLO_WORLD}
- Page Title: Title`);
expect(snapshot).toContain(`- generic [active] [ref=e1]: Hello, world!`);
});
test('close', async ({ cli, server }) => {
await cli('open', server.HELLO_WORLD);
const { output } = await cli('close');
expect(output).toContain(`Browser 'default' closed`);
});
test('preserves URL with & query params', { annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright-cli/issues/403' } }, async ({ cli, server }) => {
const url = `${server.HELLO_WORLD}?a=1&b=2`;
const { output } = await cli('open', url);
expect(output).toContain(`Page URL: ${url}`);
});
test('click button', async ({ cli, server }) => {
server.setContent('/', `<button>Submit</button>`, 'text/html');
const { snapshot } = await cli('open', server.PREFIX);
expect(snapshot).toContain(`- button "Submit" [ref=e2]`);
const { output, snapshot: clickSnapshot } = await cli('click', 'e2');
expect(clickSnapshot).toBeTruthy();
expect(output).toContain(`### Ran Playwright code
\`\`\`js
await page.getByRole('button', { name: 'Submit' }).click();
\`\`\``);
});
test('click link', async ({ cli, server }) => {
server.setContent('/', `<a href="/hello-world">Hello, world!</a>`, 'text/html');
const { snapshot } = await cli('open', server.PREFIX);
expect(snapshot).toContain(`- link \"Hello, world!\" [ref=e2]`);
const { output: clickOutput, snapshot: clickSnapshot } = await cli('click', 'e2');
expect(clickOutput).toContain(`### Page
- Page URL: ${server.HELLO_WORLD}
- Page Title: Title`);
expect(clickSnapshot).toContain('Hello, world!');
});
test('dblclick', async ({ cli, server }) => {
server.setContent('/', eventsPage, 'text/html');
await cli('open', server.PREFIX);
const { snapshot } = await cli('dblclick', 'e2');
expect(snapshot).toContain('dblclick 0');
});
test('click with --modifiers', { annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright-cli/issues/406' } }, async ({ cli, server }) => {
server.setContent('/', `<button>Submit</button>`, 'text/html');
await cli('open', server.PREFIX);
const single = await cli('click', 'e2', '--modifiers', 'Control');
expect(single.output).toContain(`await page.getByRole('button', { name: 'Submit' }).click({\n modifiers: ['Control']\n});`);
const repeated = await cli('click', 'e2', '--modifiers', 'Control', '--modifiers', 'Shift');
expect(repeated.output).toContain(`await page.getByRole('button', { name: 'Submit' }).click({\n modifiers: ['Control', 'Shift']\n});`);
});
test('type', async ({ cli, server }) => {
server.setContent('/', `<input type=text>`, 'text/html');
const { snapshot } = await cli('open', server.PREFIX);
expect(snapshot).toContain(`- textbox [ref=e2]`);
const { snapshot: typeSnapshot } = await cli('type', 'Hello, world!', '--submit');
expect(typeSnapshot).toBe(`- textbox [ref=e2]`);
});
test('fill', async ({ cli, server }) => {
server.setContent('/', `<input type=text>`, 'text/html');
const { snapshot } = await cli('open', server.PREFIX);
expect(snapshot).toContain(`- textbox [ref=e2]`);
const { snapshot: fillSnapshot } = await cli('fill', 'e2', 'Hello, world!', '--submit');
expect(fillSnapshot).toBe(`- textbox [active] [ref=e2]: Hello, world!`);
});
test('fill numeric', { annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright-cli/issues/235' } }, async ({ cli, server }) => {
server.setContent('/', `<input type=text>`, 'text/html');
const { snapshot } = await cli('open', server.PREFIX);
expect(snapshot).toContain(`- textbox [ref=e2]`);
const { snapshot: fillSnapshot } = await cli('fill', 'e2', '42', '--submit');
expect(fillSnapshot).toContain(`[ref=e2]: "42"`);
});
test('hover', async ({ cli, server }) => {
server.setContent('/', eventsPage, 'text/html');
await cli('open', server.PREFIX);
await cli('hover', 'e2');
const { inlineSnapshot } = await cli('snapshot');
expect(inlineSnapshot).toContain('mouse move 50 50');
});
test('select', async ({ cli, server }) => {
server.setContent('/', `<select><option value="1">One</option><option value="2">Two</option></select>`, 'text/html');
await cli('open', server.PREFIX);
await cli('select', 'e2', 'Two');
const { inlineSnapshot } = await cli('snapshot');
expect(inlineSnapshot).toContain('- option "Two" [selected]');
});
test('check', async ({ cli, server, mcpBrowser }) => {
const active = mcpBrowser === 'webkit' && process.platform !== 'linux' ? '' : '[active] ';
server.setContent('/', `<input type="checkbox">`, 'text/html');
await cli('open', server.PREFIX);
await cli('check', 'e2');
const { inlineSnapshot } = await cli('snapshot');
expect(inlineSnapshot).toContain(`- checkbox [checked] ${active}[ref=e2]`);
});
test('uncheck', async ({ cli, server, mcpBrowser }) => {
const active = mcpBrowser === 'webkit' && process.platform !== 'linux' ? '' : '[active] ';
server.setContent('/', `<input type="checkbox" checked>`, 'text/html');
await cli('open', server.PREFIX);
await cli('uncheck', 'e2');
const { inlineSnapshot } = await cli('snapshot');
expect(inlineSnapshot).toContain(`- checkbox ${active}[ref=e2]`);
});
test('eval', async ({ cli, server }) => {
await cli('open', server.HELLO_WORLD);
const { output } = await cli('eval', '() => document.title');
expect(output).toContain('"Title"');
});
test('eval no arrow', async ({ cli, server }) => {
await cli('open', server.HELLO_WORLD);
const { output } = await cli('eval', 'document.title');
expect(output).toContain('"Title"');
});
test('eval <ref>', async ({ cli, server }) => {
server.setContent('/', `<button>Submit</button>`, 'text/html');
await cli('open', server.PREFIX);
const { output } = await cli('eval', 'element => element.nodeName', 'e2');
expect(output).toContain('"BUTTON"');
});
test('dialog-accept', async ({ cli, server }) => {
server.setContent('/', `<button onclick="alert('MyAlert')">Button</button>`, 'text/html');
await cli('open', server.PREFIX);
const { output } = await cli('click', 'e2');
expect(output).toContain('MyAlert');
expect(output).toContain('["alert" dialog with message "MyAlert"]: can be handled by dialog-accept or dialog-dismiss');
await cli('dialog-accept');
const { inlineSnapshot } = await cli('snapshot');
expect(inlineSnapshot).not.toContain('MyAlert');
});
test('dialog-dismiss', async ({ cli, server }) => {
server.setContent('/', `<button onclick="alert('MyAlert')">Button</button>`, 'text/html');
await cli('open', server.PREFIX);
const { output } = await cli('click', 'e2');
expect(output).toContain('MyAlert');
await cli('dialog-dismiss');
const { inlineSnapshot } = await cli('snapshot');
expect(inlineSnapshot).not.toContain('MyAlert');
});
test('dialog-accept <prompt>', async ({ cli, server }) => {
server.setContent('/', `<button onclick="document.body.textContent = prompt('MyAlert')">Button</button>`, 'text/html');
await cli('open', server.PREFIX);
await cli('click', 'e2');
await cli('dialog-accept', 'my reply');
const { inlineSnapshot } = await cli('snapshot');
expect(inlineSnapshot).toContain('my reply');
});
test('resize', async ({ cli, server }) => {
await cli('open', server.PREFIX);
await cli('resize', '480', '320');
const { output } = await cli('eval', '() => window.innerWidth + "x" + window.innerHeight');
expect(output).toContain('480x320');
});
test('snapshot', async ({ cli, server }, testInfo) => {
{
const { output } = await cli('open', server.HELLO_WORLD);
expect(output).toContain('.playwright-cli' + path.sep + 'page-');
}
{
const nested = testInfo.outputPath('nested');
await fs.promises.mkdir(nested, { recursive: true });
const { output } = await cli('goto', server.HELLO_WORLD, { cwd: nested });
expect(output).toContain('..' + path.sep + '.playwright-cli' + path.sep + 'page-');
}
});
test('click in iframe', async ({ cli, server }) => {
server.setContent('/', `<h1>Hello</h1><iframe src="data:text/html,<button>World</button><main><iframe src='data:text/html,<p>Nested</p>'></iframe></main>"></iframe><iframe src="data:text/html,<h1>Should be invisible</h1>" style="display: none;"></iframe>`, 'text/html');
const { snapshot } = await cli('open', server.PREFIX);
expect(snapshot).toContain(`- button "World" [ref=f1e2]`);
const { output, snapshot: clickSnapshot } = await cli('click', 'f1e2');
expect(clickSnapshot).toBeTruthy();
expect(output).toContain(`### Ran Playwright code
\`\`\`js
await page.locator('iframe').first().contentFrame().getByRole('button', { name: 'World' }).click();
\`\`\``);
});
test('click button with CSS selector', async ({ cli, server }) => {
server.setContent('/', `<button>Submit</button>`, 'text/html');
const { snapshot } = await cli('open', server.PREFIX);
expect(snapshot).toContain(`- button "Submit" [ref=e2]`);
const { output, snapshot: clickSnapshot } = await cli('click', 'button');
expect(clickSnapshot).toBeTruthy();
expect(output).toContain(`### Ran Playwright code
\`\`\`js
await page.locator('button').click();
\`\`\``);
});
test('click button with role locator', async ({ cli, server }) => {
server.setContent('/', `<button>Submit</button>`, 'text/html');
const { snapshot } = await cli('open', server.PREFIX);
expect(snapshot).toContain(`- button "Submit" [ref=e2]`);
const { output, snapshot: clickSnapshot } = await cli('click', 'getByRole("button", { name: "Submit" })');
expect(clickSnapshot).toBeTruthy();
expect(output).toContain(`### Ran Playwright code
\`\`\`js
await page.getByRole('button', { name: 'Submit' }).click();
\`\`\``);
});
test('click button with test id locator', async ({ cli, server }) => {
server.setContent('/', `<div data-testid=main><button>Submit</button></div>`, 'text/html');
const { snapshot } = await cli('open', server.PREFIX);
expect(snapshot).toContain(`- button "Submit" [ref=e3]`);
const { output, snapshot: clickSnapshot } = await cli('click', 'getByTestId("main").getByRole("button")');
expect(clickSnapshot).toBeTruthy();
expect(output).toContain(`### Ran Playwright code
\`\`\`js
await page.getByTestId('main').getByRole('button').click();
\`\`\``);
});
test('click button with wrong css selector', async ({ cli, server }) => {
server.setContent('/', `<button>Submit</button>`, 'text/html');
const { snapshot } = await cli('open', server.PREFIX);
expect(snapshot).toContain(`- button "Submit" [ref=e2]`);
const { output } = await cli('click', '#target');
expect(output).toContain(`"#target" does not match any elements.`);
});
test('partial snapshot', async ({ cli, server }) => {
server.setContent('/', `<button id=one>Submit</button><button id=two>Cancel</button>`, 'text/html');
const { snapshot } = await cli('open', server.PREFIX);
expect(snapshot).toContain('- button "Submit" [ref=e2]');
expect(snapshot).toContain('- button "Cancel" [ref=e3]');
const { inlineSnapshot: partialSnapshot } = await cli('snapshot', '#two');
expect(partialSnapshot).toBe(`- button "Cancel" [ref=e3]`);
const { output: strictError } = await cli('snapshot', 'button');
expect(strictError).toContain(`strict mode violation`);
const { output: noMatchError } = await cli('snapshot', '#target');
expect(noMatchError).toContain(`"#target" does not match any element`);
});
test('partial snapshot by ref', { annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright-cli/issues/347' } }, async ({ cli, server }) => {
server.setContent('/', `<button id=one>Submit</button><button id=two>Cancel</button>`, 'text/html');
const { snapshot } = await cli('open', server.PREFIX);
expect(snapshot).toContain('- button "Submit" [ref=e2]');
expect(snapshot).toContain('- button "Cancel" [ref=e3]');
const { inlineSnapshot: partialSnapshot } = await cli('snapshot', 'e3');
expect(partialSnapshot).toBe(`- button "Cancel" [ref=e3]`);
const { output: missingRefError } = await cli('snapshot', 'e999');
expect(missingRefError).toContain(`Ref e999 not found in the current page snapshot.`);
});
test('snapshot depth', async ({ cli, server }) => {
server.setContent('/', `<ul><li><button id=one>Submit</button></li><li><button id=two>Cancel</button></li></ul>`, 'text/html');
await cli('open', server.PREFIX);
const { inlineSnapshot: limitedSnapshot } = await cli('snapshot', '--depth=1');
expect(limitedSnapshot).toBe(`- list [ref=e2]:
- listitem [ref=e3]
- listitem [ref=e5]`);
const { inlineSnapshot: fullSnapshot } = await cli('snapshot', '--depth=100');
expect(fullSnapshot).toBe(`- list [ref=e2]:
- listitem [ref=e3]:
- button "Submit" [ref=e4]
- listitem [ref=e5]:
- button "Cancel" [ref=e6]`);
});
test('snapshot --boxes', async ({ cli, server }) => {
server.setContent('/', `
<style>body { margin: 0; }</style>
<button style="position:absolute;left:100px;top:50px;width:80px;height:40px;margin:0;padding:0;border:0;">click</button>
`, 'text/html');
await cli('open', server.PREFIX);
const { inlineSnapshot } = await cli('snapshot', '--boxes');
expect(inlineSnapshot).toContain(`- button "click" [ref=e1] [box=100,50,80,40]`);
const { inlineSnapshot: plain } = await cli('snapshot');
expect(plain).not.toMatch(/\[box=/);
});
test('eval --raw', async ({ cli, server }) => {
await cli('open', server.HELLO_WORLD);
const { output } = await cli('eval', '--raw', '() => document.title');
expect(output).toBe('"Title"');
});
test('eval --raw with error', async ({ cli, server }) => {
await cli('open', server.HELLO_WORLD);
const { output } = await cli('eval', '--raw', '() => { throw new Error("my error") }');
expect(output).toContain('my error');
expect(output).not.toContain('##');
});
test('snapshot --raw', async ({ cli, server }) => {
server.setContent('/', `<button>Submit</button>`, 'text/html');
await cli('open', server.PREFIX);
const { output } = await cli('snapshot', '--raw');
expect(output).toBe('- button "Submit" [ref=e2]');
});
test('--raw on command without output', async ({ cli, server }) => {
server.setContent('/', `<button>Submit</button>`, 'text/html');
await cli('open', server.PREFIX);
const { output } = await cli('click', '--raw', 'e2');
expect(output).not.toContain('### ');
expect(output).not.toContain('Page URL');
});