feat: respond with action and generated locator (#181)
Closes https://github.com/microsoft/playwright-mcp/issues/163
This commit is contained in:
parent
4d59e06184
commit
4a19e18999
10 changed files with 126 additions and 52 deletions
|
|
@ -207,36 +207,52 @@ class Tab {
|
|||
await this.page.waitForLoadState('load', { timeout: 5000 }).catch(() => {});
|
||||
}
|
||||
|
||||
async run(callback: (tab: Tab) => Promise<void>, options?: RunOptions): Promise<ToolResult> {
|
||||
async run(callback: (tab: Tab) => Promise<void | string>, options?: RunOptions): Promise<ToolResult> {
|
||||
let actionCode: string | undefined;
|
||||
try {
|
||||
if (!options?.noClearFileChooser)
|
||||
this._fileChooser = undefined;
|
||||
if (options?.waitForCompletion)
|
||||
await waitForCompletion(this.page, () => callback(this));
|
||||
actionCode = await waitForCompletion(this.page, () => callback(this)) ?? undefined;
|
||||
else
|
||||
await callback(this);
|
||||
actionCode = await callback(this) ?? undefined;
|
||||
} finally {
|
||||
if (options?.captureSnapshot)
|
||||
this._snapshot = await PageSnapshot.create(this.page);
|
||||
}
|
||||
const tabList = this.context.tabs().length > 1 ? await this.context.listTabs() + '\n\nCurrent tab:' + '\n' : '';
|
||||
const snapshot = this._snapshot?.text({ status: options?.status, hasFileChooser: !!this._fileChooser }) ?? options?.status ?? '';
|
||||
|
||||
const result: string[] = [];
|
||||
if (options?.status)
|
||||
result.push(options.status, '');
|
||||
|
||||
if (this.context.tabs().length > 1)
|
||||
result.push(await this.context.listTabs(), '');
|
||||
|
||||
if (actionCode)
|
||||
result.push('- Action: ' + actionCode, '');
|
||||
|
||||
if (this._snapshot) {
|
||||
if (this.context.tabs().length > 1)
|
||||
result.push('Current tab:');
|
||||
result.push(this._snapshot.text({ hasFileChooser: !!this._fileChooser }));
|
||||
}
|
||||
|
||||
return {
|
||||
content: [{
|
||||
type: 'text',
|
||||
text: tabList + snapshot,
|
||||
text: result.join('\n'),
|
||||
}],
|
||||
};
|
||||
}
|
||||
|
||||
async runAndWait(callback: (tab: Tab) => Promise<void>, options?: RunOptions): Promise<ToolResult> {
|
||||
async runAndWait(callback: (tab: Tab) => Promise<void | string>, options?: RunOptions): Promise<ToolResult> {
|
||||
return await this.run(callback, {
|
||||
waitForCompletion: true,
|
||||
...options,
|
||||
});
|
||||
}
|
||||
|
||||
async runAndWaitWithSnapshot(callback: (snapshot: PageSnapshot) => Promise<void>, options?: RunOptions): Promise<ToolResult> {
|
||||
async runAndWaitWithSnapshot(callback: (snapshot: PageSnapshot) => Promise<void | string>, options?: RunOptions): Promise<ToolResult> {
|
||||
return await this.run(tab => callback(tab.lastSnapshot()), {
|
||||
captureSnapshot: true,
|
||||
waitForCompletion: true,
|
||||
|
|
@ -275,13 +291,9 @@ class PageSnapshot {
|
|||
return snapshot;
|
||||
}
|
||||
|
||||
text(options?: { status?: string, hasFileChooser?: boolean }): string {
|
||||
text(options: { hasFileChooser: boolean }): string {
|
||||
const results: string[] = [];
|
||||
if (options?.status) {
|
||||
results.push(options.status);
|
||||
results.push('');
|
||||
}
|
||||
if (options?.hasFileChooser) {
|
||||
if (options.hasFileChooser) {
|
||||
results.push('- There is a file chooser visible that requires browser_file_upload to be called');
|
||||
results.push('');
|
||||
}
|
||||
|
|
@ -359,3 +371,7 @@ class PageSnapshot {
|
|||
return frame.locator(`aria-ref=${ref}`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function generateLocator(locator: playwright.Locator): Promise<string> {
|
||||
return (locator as any)._generateLocatorString();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue