Skip to content

Conversation

@kevin940726
Copy link
Contributor

@kevin940726 kevin940726 commented Dec 24, 2022

Close #10437.

This feature aims to bring official support to combine sharded reports in the HTML reporter. This is probably not the best solution, but I think it works with minimal changes.

How it works

  1. We inline the shard config into a global variable along with other metadata for future usage called window.playwrightMetadata.
  2. Instead of inlining the ZIP file into a base64 string, we write the ZIP into a report.zip file. If there's sharding, we instead write them into a report-{shardIndex}.zip file.
  3. After each run, we typically upload the generated report directory somewhere to an artifact. Once every part is finished, we download and extract them to a single place. Everything except for the report-{shardIndex}.zip files should be overridden and replaced.
  4. In the web app, instead of reading the ZIP from a base64 string, we read them from HTTP. If there's sharding, we read the reports one by one and merge them together.

Comparing to playwright-merge-html-reports

The mergeStats helper is largely inspired by playwright-merge-html-reports, but I think this approach has some advantages:

  1. Official support.
  2. No extra steps are needed, no need to run another script to combine the reports. This can be tedious for CI as they have to initialize an environment, npm install, download reports, run the scripts, then finally upload the report.
  3. Works out of the box, no need for another API.

Example setup

GitHub Actions with artifacts

steps:
  playwright:
    name: 'Playwright Tests - ${{ matrix.project }} - Shard ${{ matrix.shardIndex }} of ${{ matrix.shardTotal }}'
    runs-on: ubuntu-latest
    container:
      image: mcr.microsoft.com/playwright:v1.29.0-focal
    strategy:
      fail-fast: false
      matrix:
        project: [chromium, webkit]
        shardIndex: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        shardTotal: [10]
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
      - name: Install dependencies
        run: npm ci
      - name: Run your tests
        run: npx playwright test --project=${{ matrix.project }} --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
      - uses: actions/upload-artifact@v3
        with:
          name: playwright-report
          path: playwright-report

WDYT? Once we're happy with the approach we can start writing some docs and tests.

@kevin940726
Copy link
Contributor Author

@microsoft-github-policy-service agree

@kevin940726 kevin940726 force-pushed the feat/support-sharding-in-html-reporter branch from 7bf0899 to 5364c0a Compare December 24, 2022 18:05
@kevin940726 kevin940726 changed the title feat: supports sharding in HTML Reporter feat: support sharding in HTML Reporter Dec 24, 2022
@mxschmitt mxschmitt requested a review from dgozman January 4, 2023 18:27
Copy link
Member

@pavelfeldman pavelfeldman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Sorry for the late review, just returned from the break.

}
this._json = mergeReports(reports);
} else {
const zipReader = new zipjs.ZipReader(new zipjs.HttpReader('/report/report.zip'), { useWebWorkers: false }) as zip.ZipReader;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having it all in one file is a strong requirement, let's keep it as is. Loading shards from http(s) is Ok though.

<body>
<div id='root'></div>
<script type='module' src='/src/index.tsx'></script>
<dialog id="fallback-error">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove this: we should be able to open it from file:// - it was a strong requirement from the community.

const reports: HTMLReport[] = [];
for (let index = 1; index <= metadata.shard.total; index += 1) {
try {
const zipReader = new zipjs.ZipReader(new zipjs.HttpReader(`/report/report-${index}.zip`), { useWebWorkers: false }) as zip.ZipReader;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep those files siblings in order to be less intrusive, hard-code less names. So it'll be

new zipjs.HttpReader(`report-${index}.zip`)

const currentJson = await this.entry(`report-${index}.json`) as HTMLReport;
reports.push(currentJson);
} catch (error) {
// Ignore not found error for viewing individual shard report.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make sure these errors end up in devtools so that it was clear what is going on.

for (let index = 1; index <= metadata.shard.total; index += 1) {
try {
const zipReader = new zipjs.ZipReader(new zipjs.HttpReader(`/report/report-${index}.zip`), { useWebWorkers: false }) as zip.ZipReader;
for (const entry of await zipReader.getEntries())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you could benefit from fetching them all concurrently instead.

// Inline metadata.
const indexFile = path.join(this._reportFolder, 'index.html');
fs.appendFileSync(indexFile, '<script>\nwindow.playwrightReportBase64 = "data:application/zip;base64,');
fs.appendFileSync(indexFile, `<script>\nwindow.playwrightMetadata = ${JSON.stringify(metadata)}\n</script>`);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We would need both, the new data and the base64 placeholder.

@dgozman
Copy link
Contributor

dgozman commented Jan 27, 2023

@kevin940726 Heads up: I will pick this up, create a new PR and attribute existing work in the description. This way it will be easier to manage and land the feature.

@kevin940726
Copy link
Contributor Author

@dgozman Sure! I'll be away until next week anyway (LNY), so feel free to do anything with this PR :). Also thank you @pavelfeldman for the review!

yury-s added a commit that referenced this pull request Feb 7, 2023
This implementation is based on the [original
PR](#19691) by @kevin940726.
It makes the reporter produce single file when there is no sharding and
multiple out-of-line report-x-of-y.zip reports which are automatically
merged together when put in one folder.

References #10437

Co-authored-by: Kai Hao <[email protected]>
@mxschmitt
Copy link
Contributor

Looks like got implemented in #20700. Closing for now then and thanks for the contribution!

@mxschmitt mxschmitt closed this Feb 8, 2023
@kevin940726 kevin940726 deleted the feat/support-sharding-in-html-reporter branch February 8, 2023 10:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Combine sharding with html reporter

4 participants