DEV Community

Hayden Mankin
Hayden Mankin

Posted on

Screenshot Web Elements Across Browsers in Issue Comments.

My Workflow

GitHub logo DryCreations / screenshot-workflow

This workflow will run a local server in a GitHub action, take screenshots using Playwright, upload those screenshots to Imgur, and post them as a comment on an issue or pull request.

Screenshot Workflow

This workflow will run a local server in a github action, take screenshots using Playwright, upload those screenshots to imgur, and post them as a comment on an issue or pull request.

Instructions

To activate this workflow all you need to do is leave a comment in this format:

/screenshot browser path {selector}

Your comment can contain as many of these commands as you want, the workflow will post all of the screenshots in the same comment.

browser: Represents the browser being run by playwright, try using webkit or chromium.

path: Represents the path being screenshotted by playwright, this demo project only has a root path /.

selector: An optional flag representing a query selector of an element to screenshot instead of a whole page.

These options allow contributors and maintainers to screenshot various new features, or compare issues across browser easily by…

This workflow will run a local server in a Github action, take screenshots using Playwright, upload those screenshots to Imgur, and post them as a comment on an issue or pull request.

Submission Category:

Maintainer Must-Haves

Yaml File or Link to Code

Demo Repository: https://github.com/DryCreations/screenshot-workflow

Workflow:

name: Screenshot
on: 
  issue_comment:
    types: 
      - created

jobs:
  screenshot:
    runs-on: ubuntu-latest
    container: mcr.microsoft.com/playwright:focal
    if: contains(github.event.comment.body, '/screenshot')
    steps:
    - name: Checkout Main
      if: ${{ !github.event.issue.pull_request }}
      uses: actions/checkout@v2
    - name: Get Branch for Pull Request
      if: ${{ github.event.issue.pull_request }}
      uses: xt0rted/pull-request-comment-branch@v1
      id: comment-branch
    - name: Checkout Branch
      if: ${{ github.event.issue.pull_request }}
      uses: actions/checkout@v2
      with:
        ref: ${{ steps.comment-branch.outputs.head_ref }}
    - name: Cache NPM Dependencies
      uses: actions/cache@v2
      with:
        path: ~/.npm
        key: ${{ runner.OS }}-npm-cache-${{ hashFiles('**/package-lock.json') }}
        restore-keys: |
          ${{ runner.OS }}-npm-cache-
    - name: Install Playwright
      run: |
        npm install playwright
    - name: Run Server
      run: |
        npm run start & 
        npx wait-on http://127.0.0.1:3000/
    - name: Screenshot Images
      id: sc_step
      uses: actions/github-script@v5
      with:
        github-token: ${{secrets.GITHUB_TOKEN}}
        script: |
          const { webkit, firefox, chromium } = require('playwright');

          let browsers = {
            "webkit": webkit,
            "firefox": firefox,
            "chromium": chromium
          }
          let comment_body = context.payload.comment.body;

          let matches = comment_body.matchAll(/\/screenshot (?<browser>.+?) (?<path>.+?)(\s{(?<selector>.+)})?/gm);
          let img_ctr = 0;

          for (const { groups: { browser, path, selector } } of matches) {
            console.log(browser, path, selector);
            let img_id = img_ctr++;
            (async () => {
              const b = await browsers[browser].launch();
              const page = await b.newPage();
              await page.goto(`http://127.0.0.1:3000${path}`, { waitUntil: 'domcontentloaded' });
              const element = selector ? await page.$(selector) : page;
              await element.screenshot({ path: `image-uploads/${img_id}.png` });
              await b.close();
            })()
          }
    - name: Upload to Imgur
      id: imgur_step
      uses: devicons/public-upload-to-imgur@v2.2.1
      with:
        path: image-uploads/ # or path/to/images
        client_id: ${{secrets.IMGUR_CLIENT_ID}}
    - name: Comment Images
      uses: actions/github-script@v5
      env:
        IMG_URLS: ${{ steps.imgur_step.outputs.imgur_urls }}
      with:
        github-token: ${{secrets.GITHUB_TOKEN}}
        script: |
          const { IMG_URLS } = process.env
          let img_urls = JSON.parse(IMG_URLS)
          console.log(img_urls)
          console.log(img_urls[0])

          let comment_body = context.payload.comment.body;
          let matches = comment_body.matchAll(/\/screenshot (?<params>.+? .+?(\s{.+})?)/gm);
          let params = Array.from(matches, m => m.groups.params);

          let body = img_urls.map((url, idx) => `# ${params[idx]}\n![Image](${url})`).join('\n\n')

          github.rest.issues.createComment({
            issue_number: context.issue.number,
            owner: context.repo.owner,
            repo: context.repo.repo,
            body: body
          })
Enter fullscreen mode Exit fullscreen mode

Additional Resources / Info

Relies on the following actions:

https://github.com/marketplace/actions/checkout

https://github.com/marketplace/actions/cache

https://github.com/marketplace/actions/github-script

https://github.com/marketplace/actions/publish-on-imgur

Important Notes:

If you plan on using this in your own project, you may want to play attention to line 37. Currently the project runs the following command:

npm run start
Enter fullscreen mode Exit fullscreen mode

And expects a server to start at http://127.0.0.1:3000/

If your project acts differently, or has another run command, update the command on line 37 as needed.

Discussion (0)