Files
AI/참고/playwright-main/tests/extension/tab-management.spec.ts
2026-05-12 19:40:31 +09:00

171 lines
6.4 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 { test, expect, connectAndNavigate } from './extension-fixtures';
test.skip(({ protocolVersion }) => protocolVersion === 1, 'Multi-tab not supported in protocol v1');
test(`browser_tabs new creates a new tab`, async ({ startExtensionClient, server }) => {
server.setContent('/second.html', '<title>Second</title><body>Second page<body>', 'text/html');
const { browserContext, client } = await startExtensionClient();
const navigateResponse = await connectAndNavigate(browserContext, client, server.HELLO_WORLD);
expect(navigateResponse).toHaveResponse({
snapshot: expect.stringContaining(`- generic [active] [ref=e1]: Hello, world!`),
});
const newTabResponse = await client.callTool({
name: 'browser_tabs',
arguments: { action: 'new', url: server.PREFIX + '/second.html' },
});
expect(newTabResponse).toHaveResponse({
snapshot: expect.stringContaining(`- generic [active] [ref=e1]: Second page`),
});
const listResponse = await client.callTool({
name: 'browser_tabs',
arguments: { action: 'list' },
});
expect(listResponse).toHaveResponse({
result: expect.stringMatching(/- 0: \[Title\]\(.*\/hello-world\)\n- 1: \(current\) \[Second\]\(.*\/second\.html\)/),
});
});
test(`browser_tabs select switches the active tab`, async ({ startExtensionClient, server }) => {
server.setContent('/first.html', '<title>First</title><body>First page</body>', 'text/html');
server.setContent('/second.html', '<title>Second</title><body>Second page</body>', 'text/html');
const { browserContext, client } = await startExtensionClient();
await connectAndNavigate(browserContext, client, server.PREFIX + '/first.html');
await client.callTool({
name: 'browser_tabs',
arguments: { action: 'new', url: server.PREFIX + '/second.html' },
});
const selectResponse = await client.callTool({
name: 'browser_tabs',
arguments: { action: 'select', index: 0 },
});
expect(selectResponse).toHaveResponse({
result: expect.stringMatching(/- 0: \(current\) \[First\]\(.*\/first\.html\)\n- 1: \[Second\]\(.*\/second\.html\)/),
});
const snapshotResponse = await client.callTool({
name: 'browser_snapshot',
arguments: {},
});
expect(snapshotResponse).toHaveResponse({
inlineSnapshot: expect.stringContaining('First page'),
});
});
test(`browser_tabs close removes a tab`, async ({ startExtensionClient, server }) => {
server.setContent('/first.html', '<title>First</title><body>First page</body>', 'text/html');
server.setContent('/second.html', '<title>Second</title><body>Second page</body>', 'text/html');
const { browserContext, client } = await startExtensionClient();
await connectAndNavigate(browserContext, client, server.PREFIX + '/first.html');
await client.callTool({
name: 'browser_tabs',
arguments: { action: 'new', url: server.PREFIX + '/second.html' },
});
const closeResponse = await client.callTool({
name: 'browser_tabs',
arguments: { action: 'close', index: 0 },
});
expect(closeResponse).toHaveResponse({
result: expect.stringMatching(/^- 0: \(current\) \[Second\]\(.*\/second\.html\)$/m),
});
const listResponse = await client.callTool({
name: 'browser_tabs',
arguments: { action: 'list' },
});
expect(listResponse).toHaveResponse({
result: expect.not.stringContaining('First'),
});
expect(listResponse).toHaveResponse({
result: expect.stringContaining('Second'),
});
});
test(`cmd+click opens new tab visible in tab list`, async ({ startExtensionClient, server }) => {
server.setContent('/link-page', '<title>LinkPage</title><body><a href="/target-page">click me</a></body>', 'text/html');
server.setContent('/target-page', '<title>TargetPage</title><body>Target content</body>', 'text/html');
const { browserContext, client } = await startExtensionClient();
const navigateResponse = await connectAndNavigate(browserContext, client, server.PREFIX + '/link-page');
expect(navigateResponse).toHaveResponse({
snapshot: expect.stringContaining(`click me`),
});
await client.callTool({
name: 'browser_click',
arguments: { element: 'click me', target: 'e2', modifiers: ['ControlOrMeta'] },
});
await expect.poll(async () => {
const listResponse = await client.callTool({
name: 'browser_tabs',
arguments: { action: 'list' },
});
return (listResponse as any).content?.[0]?.text ?? '';
}).toContain('TargetPage');
const listResponse = await client.callTool({
name: 'browser_tabs',
arguments: { action: 'list' },
});
expect(listResponse).toHaveResponse({
result: expect.stringMatching(/- 0:.*\[LinkPage\].*\n- 1:.*\[TargetPage\]/),
});
});
test(`window.open from tracked tab auto-attaches new tab`, async ({ startExtensionClient, server }) => {
server.setContent('/opener-page', `<title>Opener</title><body><button onclick="window.open('${server.PREFIX}/opened-page', '_blank', 'noopener')">open</button></body>`, 'text/html');
server.setContent('/opened-page', '<title>Opened</title><body>Opened content</body>', 'text/html');
const { browserContext, client } = await startExtensionClient();
const navigateResponse = await connectAndNavigate(browserContext, client, server.PREFIX + '/opener-page');
expect(navigateResponse).toHaveResponse({
snapshot: expect.stringContaining('open'),
});
await client.callTool({
name: 'browser_click',
arguments: { element: 'open', target: 'e2' },
});
await expect.poll(async () => {
const listResponse = await client.callTool({
name: 'browser_tabs',
arguments: { action: 'list' },
});
return (listResponse as any).content?.[0]?.text ?? '';
}).toContain('Opened');
const listResponse = await client.callTool({
name: 'browser_tabs',
arguments: { action: 'list' },
});
expect(listResponse).toHaveResponse({
result: expect.stringMatching(/- 0:.*\[Opener\].*\n- 1:.*\[Opened\]/),
});
});