add button

This commit is contained in:
Simon Knott 2025-02-06 17:05:12 +01:00
parent 6624c96db1
commit b7b7c2d7e7
No known key found for this signature in database
GPG key ID: 8CEDC00028084AEC
4 changed files with 22 additions and 11 deletions

View file

@ -7,6 +7,8 @@ import { defineConfig, devices } from '@playwright/test';
*/ */
export default defineConfig({ export default defineConfig({
populateGitInfo: true,
testDir: './tests', testDir: './tests',
/* Maximum time one test can run for. */ /* Maximum time one test can run for. */

View file

@ -36,6 +36,7 @@ test.describe('New Todo', () => {
await expect(page.getByTestId('todo-title')).toHaveText([ await expect(page.getByTestId('todo-title')).toHaveText([
TODO_ITEMS[0], TODO_ITEMS[0],
TODO_ITEMS[1], TODO_ITEMS[1],
'faux'
]); ]);
await checkNumberOfTodosInLocalStorage(page, 2); await checkNumberOfTodosInLocalStorage(page, 2);

View file

@ -24,11 +24,12 @@ import { GitCommitInfoContext } from './reportView';
export const TestErrorView: React.FC<{ export const TestErrorView: React.FC<{
error: string; error: string;
testId?: string; testId?: string;
}> = ({ error, testId }) => { hidePrompt?: boolean;
}> = ({ error, testId, hidePrompt }) => {
const html = React.useMemo(() => ansiErrorToHtml(error), [error]); const html = React.useMemo(() => ansiErrorToHtml(error), [error]);
return ( return (
<div className='test-error-view test-error-text' data-testid={testId}> <div className='test-error-view test-error-text' data-testid={testId}>
<PromptButton error={error} /> {!hidePrompt && <PromptButton error={error} />}
<div dangerouslySetInnerHTML={{ __html: html || '' }}></div> <div dangerouslySetInnerHTML={{ __html: html || '' }}></div>
</div> </div>
); );
@ -42,6 +43,7 @@ export function stripAnsiEscapes(str: string): string {
const PromptButton: React.FC<{ const PromptButton: React.FC<{
error: string; error: string;
}> = ({ error }) => { }> = ({ error }) => {
const [copied, setCopied] = React.useState(false);
const gitCommitInfo = React.useContext(GitCommitInfoContext); const gitCommitInfo = React.useContext(GitCommitInfoContext);
if (!gitCommitInfo) if (!gitCommitInfo)
return undefined; return undefined;
@ -51,14 +53,20 @@ const PromptButton: React.FC<{
return undefined; return undefined;
return ( return (
<button onClick={() => { <button
navigator.clipboard.writeText([ style={{ width: 200, padding: '10px', marginBottom: '10px', borderRadius: '5px', border: '1px solid #ccc', backgroundColor: copied ? '#4caf50' : '#f0f0f0', color: copied ? '#fff' : '#000', cursor: 'pointer' }}
onClick={async () => {
await navigator.clipboard.writeText([
'You are a helpful assistant. Help me understand the error cause. Here is the error:', 'You are a helpful assistant. Help me understand the error cause. Here is the error:',
stripAnsiEscapes(error), stripAnsiEscapes(error),
'And this is the code diff:', 'And this is the code diff:',
diff diff
].join('\n')); ].join('\n\n'));
}}>Copy AI Prompt</button> setCopied(true);
setTimeout(() => setCopied(false), 1000);
}}>
{copied ? 'Copied!' : 'Copy prompt to fix with AI'}
</button>
); );
}; };

View file

@ -182,7 +182,7 @@ const StepTreeItem: React.FC<{
{step.count > 1 && <> <span className='test-result-counter'>{step.count}</span></>} {step.count > 1 && <> <span className='test-result-counter'>{step.count}</span></>}
{step.location && <span className='test-result-path'> {step.location.file}:{step.location.line}</span>} {step.location && <span className='test-result-path'> {step.location.file}:{step.location.line}</span>}
</span>} loadChildren={step.steps.length || step.snippet ? () => { </span>} loadChildren={step.steps.length || step.snippet ? () => {
const snippet = step.snippet ? [<TestErrorView testId='test-snippet' key='line' error={step.snippet}/>] : []; const snippet = step.snippet ? [<TestErrorView testId='test-snippet' key='line' error={step.snippet} hidePrompt />] : [];
const steps = step.steps.map((s, i) => <StepTreeItem key={i} step={s} depth={depth + 1} result={result} test={test} />); const steps = step.steps.map((s, i) => <StepTreeItem key={i} step={s} depth={depth + 1} result={result} test={test} />);
return snippet.concat(steps); return snippet.concat(steps);
} : undefined} depth={depth}/>; } : undefined} depth={depth}/>;