diff --git a/packages/html-reporter/src/testErrorView.tsx b/packages/html-reporter/src/testErrorView.tsx index bfa7b7bfd9..2dcebbad9a 100644 --- a/packages/html-reporter/src/testErrorView.tsx +++ b/packages/html-reporter/src/testErrorView.tsx @@ -23,6 +23,7 @@ import { ImageDiffView } from '@web/shared/imageDiffView'; import { GitCommitInfoContext } from './reportView'; import { TestResult } from './types'; import { CopyToClipboard } from './copyToClipboard'; +import { fixTestPrompt } from '@web/components/prompts'; export const TestErrorView: React.FC<{ error: string; testId?: string; result?: TestResult }> = ({ error, testId, result }) => { return ( @@ -44,43 +45,16 @@ export const CodeSnippet = ({ code, children, testId }: React.PropsWithChildren< ); }; -const ansiRegex = new RegExp('([\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~])))', 'g'); -function stripAnsiEscapes(str: string): string { - return str.replace(ansiRegex, ''); -} - const PromptButton: React.FC<{ error: string; result?: TestResult; }> = ({ error, result }) => { const gitCommitInfo = React.useContext(GitCommitInfoContext); - const prompt = React.useMemo(() => { - const promptParts = [ - 'This test failed, suggest how to fix it. Please be correct, concise and keep Playwright best practices in mind.', - 'Here is the error:', - '\n', - stripAnsiEscapes(error), - '\n', - ]; - - const pageSnapshot = result?.attachments.find(a => a.name === 'pageSnapshot')?.body; - if (pageSnapshot) - promptParts.push( - 'This is how the page looked at the end of the test:', - pageSnapshot, - '\n' - ); - - const diff = gitCommitInfo?.['pull.diff'] ?? gitCommitInfo?.['revision.diff']; - if (diff) - promptParts.push( - 'And this is the code diff:', - diff, - '\n' - ); - - return promptParts.join('\n'); - }, [gitCommitInfo, result, error]) + const prompt = React.useMemo(() => fixTestPrompt( + error, + gitCommitInfo?.['pull.diff'] ?? gitCommitInfo?.['revision.diff'], + result?.attachments.find(a => a.name === 'pageSnapshot')?.body + ), [gitCommitInfo, result, error]) return } title="Copy prompt to clipboard" />; }; diff --git a/packages/web/src/components/prompts.ts b/packages/web/src/components/prompts.ts new file mode 100644 index 0000000000..628a20aba9 --- /dev/null +++ b/packages/web/src/components/prompts.ts @@ -0,0 +1,46 @@ +/** + * 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. + */ + +const ansiRegex = new RegExp('([\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~])))', 'g'); +function stripAnsiEscapes(str: string): string { + return str.replace(ansiRegex, ''); +} + +export function fixTestPrompt(error: string, diff?: string, pageSnapshot?: string) { + const promptParts = [ + 'This test failed, suggest how to fix it. Please be correct, concise and keep Playwright best practices in mind.', + 'Here is the error:', + '\n', + stripAnsiEscapes(error), + '\n', + ]; + + if (pageSnapshot) + promptParts.push( + 'This is how the page looked at the end of the test:', + pageSnapshot, + '\n' + ); + + if (diff) + promptParts.push( + 'And this is the code diff:', + diff, + '\n' + ); + + return promptParts.join('\n'); +}