Skip to content

Commit

Permalink
cherry-pick(9732): fix(trace-viewer): show source files in local version
Browse files Browse the repository at this point in the history
  • Loading branch information
pavelfeldman committed Oct 25, 2021
1 parent 676a2a0 commit 0f38535
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 44 deletions.
19 changes: 9 additions & 10 deletions packages/playwright-core/src/server/trace/viewer/traceViewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,16 @@ import { ProgressController } from '../../progress';

export async function showTraceViewer(traceUrl: string, browserName: string, headless = false, port?: number): Promise<BrowserContext | undefined> {
const server = new HttpServer();
server.routePath('/file', (request, response) => {
try {
const path = new URL('http://localhost' + request.url!).searchParams.get('path')!;
return server.serveFile(response, path);
} catch (e) {
return false;
server.routePrefix('/trace', (request, response) => {
const url = new URL('http://localhost' + request.url!);
const relativePath = url.pathname.slice('/trace'.length);
if (relativePath.startsWith('/file')) {
try {
return server.serveFile(response, url.searchParams.get('path')!);
} catch (e) {
return false;
}
}
});

server.routePrefix('/', (request, response) => {
const relativePath = new URL('http://localhost' + request.url!).pathname.slice('/trace'.length);
const absolutePath = path.join(__dirname, '..', '..', '..', 'webpack', 'traceViewer', ...relativePath.split('/'));
return server.serveFile(response, absolutePath);
});
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/web/traceViewer/sw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ async function loadTrace(trace: string, clientId: string, progress: (done: numbe
if (entry)
return entry.traceModel;
const traceModel = new TraceModel();
let url = trace.startsWith('http') || trace.startsWith('blob') ? trace : `/file?path=${trace}`;
let url = trace.startsWith('http') || trace.startsWith('blob') ? trace : `file?path=${trace}`;
// Dropbox does not support cors.
if (url.startsWith('https://www.dropbox.com/'))
url = 'https://dl.dropboxusercontent.com/' + url.substring('https://www.dropbox.com/'.length);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export const SourceTab: React.FunctionComponent<{
} else {
const filePath = stackInfo.frames[selectedFrame].file;
if (!stackInfo.fileContent.has(filePath))
stackInfo.fileContent.set(filePath, await fetch(`/file?${filePath}`).then(response => response.text()).catch(e => `<Unable to read "${filePath}">`));
stackInfo.fileContent.set(filePath, await fetch(`file?path=${filePath}`).then(response => response.text()).catch(e => `<Unable to read "${filePath}">`));
value = stackInfo.fileContent.get(filePath)!;
}
return value;
Expand Down
16 changes: 10 additions & 6 deletions packages/playwright-core/src/web/traceViewer/ui/workbench.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,15 @@ export const Workbench: React.FunctionComponent<{
const consoleCount = errors + warnings;
const networkCount = selectedAction ? modelUtil.resourcesForAction(selectedAction).length : 0;

const tabs = [
{ id: 'logs', title: 'Call', count: 0, render: () => <CallTab action={selectedAction} /> },
{ id: 'console', title: 'Console', count: consoleCount, render: () => <ConsoleTab action={selectedAction} /> },
{ id: 'network', title: 'Network', count: networkCount, render: () => <NetworkTab action={selectedAction} /> },
];

if (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1')
tabs.push({ id: 'source', title: 'Source', count: 0, render: () => <SourceTab action={selectedAction} /> });

return <div className='vbox workbench'
onDragOver={event => { event.preventDefault(); }}
onDrop={event => handleDropEvent(event)}>
Expand All @@ -118,12 +127,7 @@ export const Workbench: React.FunctionComponent<{
<SplitView sidebarSize={300} orientation='horizontal' sidebarIsFirst={true}>
<SplitView sidebarSize={300} orientation='horizontal'>
<SnapshotTab action={selectedAction} defaultSnapshotSize={defaultSnapshotSize} />
<TabbedPane tabs={[
{ id: 'logs', title: 'Call', count: 0, render: () => <CallTab action={selectedAction} /> },
{ id: 'console', title: 'Console', count: consoleCount, render: () => <ConsoleTab action={selectedAction} /> },
{ id: 'network', title: 'Network', count: networkCount, render: () => <NetworkTab action={selectedAction} /> },
{ id: 'source', title: 'Source', count: 0, render: () => <SourceTab action={selectedAction} /> },
]} selectedTab={selectedTab} setSelectedTab={setSelectedTab}/>
<TabbedPane tabs={tabs} selectedTab={selectedTab} setSelectedTab={setSelectedTab}/>
</SplitView>
<ActionList
actions={contextEntry.actions}
Expand Down
25 changes: 19 additions & 6 deletions packages/playwright-test/src/reporters/html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,20 +159,33 @@ export async function showHTMLReport(reportFolder: string | undefined) {
process.exit(1);
return;
}
const server = startHtmlReportServer(folder);
const url = await server.start(9323);
console.log('');
console.log(colors.cyan(` Serving HTML report at ${url}. Press Ctrl+C to quit.`));
open(url);
process.on('SIGINT', () => process.exit(0));
await new Promise(() => {});
}

export function startHtmlReportServer(folder: string): HttpServer {
const server = new HttpServer();
server.routePrefix('/', (request, response) => {
let relativePath = new URL('http://localhost' + request.url).pathname;
if (relativePath.startsWith('/trace/file')) {
const url = new URL('http://localhost' + request.url!);
try {
return server.serveFile(response, url.searchParams.get('path')!);
} catch (e) {
return false;
}
}
if (relativePath === '/')
relativePath = '/index.html';
const absolutePath = path.join(folder, ...relativePath.split('/'));
return server.serveFile(response, absolutePath);
});
const url = await server.start(9323);
console.log('');
console.log(colors.cyan(` Serving HTML report at ${url}. Press Ctrl+C to quit.`));
open(url);
process.on('SIGINT', () => process.exit(0));
await new Promise(() => {});
return server;
}

class HtmlBuilder {
Expand Down
48 changes: 38 additions & 10 deletions tests/playwright-test/reporter-html.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,16 @@
*/

import fs from 'fs';
import path from 'path';
import { test as baseTest, expect } from './playwright-test-fixtures';
import { HttpServer } from 'playwright-core/src/utils/httpServer';
import { HttpServer } from 'playwright-core/lib/utils/httpServer';
import { startHtmlReportServer } from '../../packages/playwright-test/lib/reporters/html';

const test = baseTest.extend<{ showReport: () => Promise<void> }>({
showReport: async ({ page }, use, testInfo) => {
const server = new HttpServer();
let server: HttpServer;
await use(async () => {
const reportFolder = testInfo.outputPath('playwright-report');
server.routePrefix('/', (request, response) => {
let relativePath = new URL('http://localhost' + request.url).pathname;
if (relativePath === '/')
relativePath = '/index.html';
const absolutePath = path.join(reportFolder, ...relativePath.split('/'));
return server.serveFile(response, absolutePath);
});
server = startHtmlReportServer(reportFolder);
const location = await server.start();
await page.goto(location);
});
Expand Down Expand Up @@ -263,3 +257,37 @@ test('should highlight error', async ({ runInlineTest, page, showReport }) => {
await page.click('text=fails');
await expect(page.locator('.error-message span:has-text("received")').nth(1)).toHaveCSS('color', 'rgb(204, 0, 0)');
});

test('should show trace source', async ({ runInlineTest, page, showReport }) => {
const result = await runInlineTest({
'playwright.config.js': `
module.exports = { use: { trace: 'on' } };
`,
'a.test.js': `
const { test } = pwt;
test('passes', async ({ page }) => {
await page.evaluate('2 + 2');
});
`,
}, { reporter: 'dot,html' });
expect(result.exitCode).toBe(0);
expect(result.passed).toBe(1);

await showReport();
await page.click('text=passes');
await page.click('img');
await page.click('.action-title >> text=page.evaluate');
await page.click('text=Source');

await expect(page.locator('.source-line')).toContainText([
/const.*pwt;/,
/page\.evaluate/
]);
await expect(page.locator('.source-line-running')).toContainText('page.evaluate');

await expect(page.locator('.stack-trace-frame')).toContainText([
/a.test.js:[\d]+/,
/fixtures.[tj]s:[\d]+/,
]);
await expect(page.locator('.stack-trace-frame.selected')).toContainText('a.test.js');
});
24 changes: 14 additions & 10 deletions tests/trace-viewer/trace-viewer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,6 @@ test('should have network requests', async ({ showTraceViewer }) => {
});

test('should capture iframe', async ({ page, server, browserName, runAndTrace }) => {
test.skip(browserName === 'firefox');

await page.route('**/empty.html', route => {
route.fulfill({
body: '<iframe src="iframe.html"></iframe>',
Expand Down Expand Up @@ -394,8 +392,6 @@ test('should work with adopted style sheets and replace/replaceSync', async ({ p
});

test('should restore scroll positions', async ({ page, runAndTrace, browserName }) => {
test.skip(browserName === 'firefox');

const traceViewer = await runAndTrace(async () => {
await page.setContent(`
<style>
Expand Down Expand Up @@ -428,8 +424,6 @@ test('should restore scroll positions', async ({ page, runAndTrace, browserName
});

test('should work with meta CSP', async ({ page, runAndTrace, browserName }) => {
test.skip(browserName === 'firefox');

const traceViewer = await runAndTrace(async () => {
await page.setContent(`
<head>
Expand All @@ -455,8 +449,6 @@ test('should work with meta CSP', async ({ page, runAndTrace, browserName }) =>
});

test('should handle multiple headers', async ({ page, server, runAndTrace, browserName }) => {
test.skip(browserName === 'firefox');

server.setRoute('/foo.css', (req, res) => {
res.statusCode = 200;
res.setHeader('vary', ['accepts-encoding', 'accepts-encoding']);
Expand Down Expand Up @@ -499,8 +491,6 @@ test('should handle src=blob', async ({ page, server, runAndTrace, browserName }
});

test('should highlight target elements', async ({ page, runAndTrace, browserName }) => {
test.skip(browserName === 'firefox');

const traceViewer = await runAndTrace(async () => {
await page.setContent(`
<div>hello</div>
Expand Down Expand Up @@ -537,3 +527,17 @@ test('should highlight target elements', async ({ page, runAndTrace, browserName
const frameExpect2 = await traceViewer.snapshotFrame('expect.toHaveText', 1);
await expect(frameExpect2.locator('[__playwright_target__]')).toHaveText(['hello', 'world']);
});

test('should show action source', async ({ showTraceViewer }) => {
const traceViewer = await showTraceViewer(traceFile);
await traceViewer.selectAction('page.click');
const page = traceViewer.page;

await page.click('text=Source');
await expect(page.locator('.source-line')).toContainText([
/async.*function.*doClick/,
/page\.click/
]);
await expect(page.locator('.source-line-running')).toContainText('page.click');
await expect(page.locator('.stack-trace-frame.selected')).toHaveText(/doClick.*trace-viewer\.spec\.ts:[\d]+/);
});

0 comments on commit 0f38535

Please sign in to comment.