Skip to content

Commit

Permalink
Add playwright initial setup and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
gwenf committed May 14, 2024
1 parent 22d8473 commit c33f950
Show file tree
Hide file tree
Showing 9 changed files with 1,013 additions and 9 deletions.
165 changes: 165 additions & 0 deletions .github/workflows/playwright copy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
name: Playwright Test Preparation

pull_request:
types: [opened, synchronize, reopened, ready_for_review]

jobs:
get-changed-files:
runs-on: ubuntu-latest
outputs:
changed-files: ${{ steps.changed_files.outputs.changed-files }}
steps:
- name: Get Changed Files
id: changed_files
uses: actions/github-script@v6
with:
script: |
const { context } = require('@actions/github');
const fs = require('fs');
const changedFiles = fs.readFileSync(context.payload.pull_request.patch_url, 'utf-8')
.match(/^\+(?:\s*\w+\/)*(\S+\.ts)$/gm)
.map(line => line.replace('+', '').trim());
core.setOutput('changed-files', JSON.stringify(changedFiles));
analyze-and-trigger:
runs-on: ubuntu-latest
needs: get-changed-files
steps:
- name: Call Test Selection API
id: test_selection
run: |
changed_files=${{ steps.changed_files.outputs.changed-files }}
tests=$(curl -X POST 'https://tests-selection.azurewebsites.net/api' \
-H 'Content-Type: application/json' \
-d "$changed_files")
echo "::set-output name=selected-tests::$tests"
- name: Analyze Test Timings and Determine Shard Count
uses: actions/github-script@v6
run: |
const testsData = JSON.parse('${{ steps.test_selection.outputs.selected-tests }}');
const totalTestDuration = testsData.reduce((sum, test) => sum + test.duration, 0);
const targetDurationPerShard = 5 * 60; // assuming 5 minutes per shard
const optimalShardCount = Math.ceil(totalTestDuration / targetDurationPerShard);
const shardIndices = [];
for (let i = 1; i <= optimalShardCount; i++) {
shardIndices.push(i);
}
core.setOutput('optimal_shard_count', optimalShardCount);
core.setOutput('shard_indices', JSON.stringify(shardIndices));
- name: Trigger Workflow 2 with Shard Count
uses: benc-uk/workflow-dispatch@v1
with:
workflow: playwright.yml
inputs: '{"shardCount": "${{ optimal_shard_count }}"}'


name: Run Playwright Tests

on:
workflow_dispatch:
inputs:
shardCount:
description: 'Number of shards to use'
required: true
type: string
shardIndices:
description: 'Array of shard indices to execute'
required: true
type: string

jobs:
check-dependencies:
runs-on: ubuntu-latest
needs: get-changed-files
outputs:
should-install-fresh-deps: ${{ steps.check_deps.outputs.should-install }}
steps:
- name: Check if package files changed
id: check_deps
run: |
changed_files=(${CHANGED_FILES})
if [[ " ${changed_files[*]} " =~ "package.json" || " ${changed_files[*]} " =~ "package-lock.json" ]]; then
echo "::set-output name=should-install::true"
else
echo "::set-output name=should-install::false"
fi
install-and-cache-node-deps:
runs-on: ubuntu-latest
needs: check-dependencies
if: steps.check_deps.outputs.should-install == 'true'
steps:
- name: Install dependencies (Vue app)
working-directory: vue-app
run: npm ci

- name: Cache Node Dependencies
uses: actions/cache@v3
with:
path: vue-app/node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
build-and-start-vue:
runs-on: ubuntu-latest
needs: check-dependencies
if: steps.check_deps.outputs.should-install == 'false'
steps:
- name: Use cached Node dependencies
uses: actions/cache@v3
with:
path: vue-app/node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Start Vue app
run: npm run dev & # Runs in background

- name: Make sure Vue server is up and running
run: |
until $(curl --output /dev/null --silent --head --fail http://localhost:3000); do
printf '.'
sleep 3
done
echo "Vue server is up and running!"
playwright-setup:
runs-on: ubuntu-latest
steps:
- name: Cache Playwright Dependencies
uses: actions/cache@v3
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ hashFiles('package-lock.json') }}
restore-keys: |
${{ runner.os }}-playwright-
- name: Install Playwright (if not cached)
if: steps.cache.outputs.cache-hit != 'true'
run: npx playwright install --with-deps

run-playwright-tests:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
shardIndex: ${{ fromJson(github.event.inputs.outputs.shard_indices) }}
shardTotal: [ ${{ github.event.inputs.shardCount }} ]
timeout-minutes: 10
needs: [call-test-selection-api, get-changed-files, playwright-setup, build-and-start-vue]
env:
CI: true
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18

- name: Run Playwright Tests
run: |
tests=${{ steps.test_selection.outputs.selected-tests }}
npx playwright test $tests --max-failures=2 --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
146 changes: 146 additions & 0 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
name: Clear Playwright Cache

on:
schedule:
- cron: '0 0 */7 * *' # runs weekly

jobs:
clear-cache:
runs-on: ubuntu-latest
steps:
- uses: actions/cache@v3
with:
path: ~/.cache/ms-playwright
restore-keys: |
${{ runner.os }}-playwright-
name: run e2e tests for vue

pull_request:
types: [opened, synchronize, reopened, ready_for_review]

jobs:
get-changed-files:
runs-on: ubuntu-latest
outputs:
changed-files: ${{ steps.changed_files.outputs.changed-files }}
steps:
- name: Get Changed Files
id: changed_files
uses: actions/github-script@v6
with:
script: |
const { context } = require('@actions/github');
const fs = require('fs');
const changedFiles = fs.readFileSync(context.payload.pull_request.patch_url, 'utf-8')
.match(/^\+(?:\s*\w+\/)*(\S+\.ts)$/gm)
.map(line => line.replace('+', '').trim());
core.setOutput('changed-files', JSON.stringify(changedFiles));
check-dependencies:
runs-on: ubuntu-latest
needs: get-changed-files
outputs:
should-install-fresh-deps: ${{ steps.check_deps.outputs.should-install }}
steps:
- name: Check if package files changed
id: check_deps
run: |
changed_files=(${CHANGED_FILES})
if [[ " ${changed_files[*]} " =~ "package.json" || " ${changed_files[*]} " =~ "package-lock.json" ]]; then
echo "::set-output name=should-install::true"
else
echo "::set-output name=should-install::false"
fi
install-and-cache-node-deps:
runs-on: ubuntu-latest
needs: check-dependencies
if: steps.check_deps.outputs.should-install == 'true'
steps:
- name: Install dependencies (Vue app)
working-directory: vue-app
run: npm ci

- name: Cache Node Dependencies
uses: actions/cache@v3
with:
path: vue-app/node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
build-and-start-vue:
runs-on: ubuntu-latest
needs: check-dependencies
if: steps.check_deps.outputs.should-install == 'false'
steps:
- name: Use cached Node dependencies
uses: actions/cache@v3
with:
path: vue-app/node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Start Vue app
run: npm run dev & # Runs in background

- name: Make sure Vue server is up and running
run: |
until $(curl --output /dev/null --silent --head --fail http://localhost:3000); do
printf '.'
sleep 3
done
echo "Vue server is up and running!"
playwright-setup:
runs-on: ubuntu-latest
steps:
- name: Cache Playwright Dependencies
uses: actions/cache@v3
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ hashFiles('package-lock.json') }}
restore-keys: |
${{ runner.os }}-playwright-
- name: Install Playwright (if not cached)
if: steps.cache.outputs.cache-hit != 'true'
run: npx playwright install --with-deps

call-test-selection-api:
runs-on: ubuntu-latest
needs: [get-changed-files]
steps:
- name: Call the Test Selection API
id: test_selection
run: |
changed_files=${{ steps.changed_files.outputs.changed-files }}
tests=$(curl -X POST 'https://tests-selection.azurewebsites.net/api' \
-H 'Content-Type: application/json' \
-d "$changed_files")
echo "selected-tests::$tests"
run-playwright-tests:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
shardIndex: [1, 2, 3, 4]
shardTotal: [4]
timeout-minutes: 10
needs: [call-test-selection-api, get-changed-files, playwright-setup, build-and-start-vue]
env:
CI: true
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18

- name: Run Playwright Tests
run: |
tests=${{ steps.test_selection.outputs.selected-tests }}
npx playwright test $tests --max-failures=2 --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
27 changes: 27 additions & 0 deletions curriculum-front/.github/workflows/playwright.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Playwright Tests
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Install dependencies
run: npm ci
- name: Install Playwright Browsers
run: npx playwright install --with-deps
- name: Run Playwright tests
run: npx playwright test
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: playwright-report/
retention-days: 30
4 changes: 4 additions & 0 deletions curriculum-front/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,7 @@ yarn-error.log*
*.njsproj
*.sln
*.sw?
/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/
19 changes: 19 additions & 0 deletions curriculum-front/e2e/example.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// @ts-check
const { test, expect } = require('@playwright/test');

test('has title', async ({ page }) => {
await page.goto('https://playwright.dev/');

// Expect a title "to contain" a substring.
await expect(page).toHaveTitle(/Playwright/);
});

test('get started link', async ({ page }) => {
await page.goto('https://playwright.dev/');

// Click the get started link.
await page.getByRole('link', { name: 'Get started' }).click();

// Expects page to have a heading with the name of Installation.
await expect(page.getByRole('heading', { name: 'Installation' })).toBeVisible();
});
Loading

0 comments on commit c33f950

Please sign in to comment.