Skip to content

Commit

Permalink
feat: dsw-2088 - basic SSR testing (#159)
Browse files Browse the repository at this point in the history
* feat: dsw-2088-webc-ssr

* basic SSR test

* name formatting

* nuxt app snapshots

* remove page object from ssr test file

* add ssr test to nextjs apps CI

* latest webc package

* add sample snapshots for nuxt and next14

* test for shadow dom markup

* test for style tag

* enable nuxt CI checks

* fix vanilla tests

* add icon button

* remove type module from package.json

* rename variable

* remove ssr tests from next13

* add chip ssr test

* add label ssr test

* add spinner ssr test

* add link ssr test

* add tag ssr test

* adjust nuxt playwright report path

* add switch ssr test

* remove second switch in test

* add back all controls

* add checkbox ssr test

* add modal ssr test

* add cookie banner ssr test

* run SSR tests before system

* add text input ssr test

* switch off nuxt system text

* require wdio config

* Trigger Build

* Trigger CI

* Trigger CI

* Trigger CI

* handle http and https

* update readme

* unskip vrt

* Trigger CI

* update vrt

* Trigger CI

* add ssr test log

* remove log

* disable visual tests in nuxt

* remove snapshot check from ssr tests

---------

Co-authored-by: pie-design-system-bot <136586628+pie-design-system-bot@users.noreply.github.com>
  • Loading branch information
jamieomaguire and pie-design-system-bot committed Jun 20, 2024
1 parent 98fb12c commit e4d4ae5
Show file tree
Hide file tree
Showing 15 changed files with 251 additions and 126 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/ci-nextjs-v14.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ jobs:
- name: Setup Playwright
uses: ./.github/actions/setup-playwright

- name: Run SSR Tests
shell: bash
run: yarn test:ssr --filter=nextjs-app-v14

- name: Run System Tests
shell: bash
run: yarn test:system --filter=nextjs-app-v14
Expand Down
82 changes: 44 additions & 38 deletions .github/workflows/ci-nuxtjs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,47 +70,53 @@ jobs:
bucket-name-main: 'pie-aperture'
secrets: inherit

# browser-tests:
# needs: 'build-deploy-nuxt-app-ubuntu-node20'
# name: Run System / Visual Tests
# runs-on: ubuntu-latest
# steps:
# # Checkout the Repo
# - name: Checkout
# uses: actions/checkout@v3
browser-tests:
needs: 'build-deploy-nuxt-app-ubuntu-node20'
name: Run System / Visual Tests
runs-on: ubuntu-latest
steps:
# Checkout the Repo
- name: Checkout
uses: actions/checkout@v3

# # Setup Node
# - name: Setup Node
# uses: actions/setup-node@v4
# with:
# node-version: 20
# cache: "yarn"
# Setup Node
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: "yarn"

# - name: Install Dependencies
# shell: bash
# run: yarn
- name: Install Dependencies
shell: bash
run: yarn

# # Setup Playwright
# - name: Setup Playwright
# uses: ./.github/actions/setup-playwright
# Setup Playwright
- name: Setup Playwright
uses: ./.github/actions/setup-playwright

- name: Run SSR Tests
shell: bash
run: yarn test:ssr --filter=nuxt-app

# - name: Run System Tests
# shell: bash
# run: yarn test:system --filter=nuxt-app
# TODO - fix this test in DSW-2157
# - name: Run System Tests
# shell: bash
# run: yarn test:system --filter=nuxt-app

# - uses: actions/upload-artifact@v3
# if: always()
# with:
# name: nuxt-playwright-report
# path: playwright-reports/nuxt-playwright-report/
# retention-days: 7
- uses: actions/upload-artifact@v3
if: always()
with:
name: nuxt-playwright-report
path: playwright-reports/nuxt-app-playwright-report/
retention-days: 7

# - name: Run Percy Tests
# shell: bash
# run: yarn test:visual --filter=nuxt-app
# env:
# BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
# BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
# NUXT_AMPLIFY_ID: d36dan3bxjue8c
# PERCY_TOKEN_PIE_APERTURE_NUXT: ${{ secrets.PERCY_TOKEN_PIE_APERTURE_NUXT }}
# PR_NUMBER: ${{ github.event.number }}
# TODO - fix this test in DSW-2158
# - name: Run Percy Tests
# shell: bash
# run: yarn test:visual --filter=nuxt-app
env:
BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
NUXT_AMPLIFY_ID: d36dan3bxjue8c
PERCY_TOKEN_PIE_APERTURE_NUXT: ${{ secrets.PERCY_TOKEN_PIE_APERTURE_NUXT }}
PR_NUMBER: ${{ github.event.number }}
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,13 @@ Playwright is used to facilitate system testing. This ensures that components fu
Given that the goal of this repo is to ensure consistent implementation of our components, we follow an approach where a single test can be executed across our test applications. This has a number of key benefits such as reduced duplication of tests and consistent DOM structure of our implemented components.

#### Tests
All shared tests live within the `test/system` folder at the root of the monorepo.
We have two kinds of testing that are shared between applications. These are `system` and `ssr`. These can be found in `test/system` and `test/ssr` respectively at the root of the monorepo..

The system tests are to test the functionality of components working together, potentially in an E2E fashion. An example could be filling in and submitting a form.

The SSR tests are to test that when the components are rendered on the server in our different applications, they are rendered correctly (have a template with shadow DOM attributes and styles).

The only application that does not get SSR tested is the vanilla application, as it does not have server-side rendering.

Should you need to add a test for a specific application due to implementation differences, these can be added to the `test/system` folder within the application root directory.

Expand Down
4 changes: 2 additions & 2 deletions nextjs-app-v13/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
"preview": "next start",
"lint": "next lint",
"playwright:show-report": "npx playwright show-report ../playwright-reports/nextjs-app-v13-playwright-report",
"test:system": "APP_NAME=nextjs-app-v13 playwright test -c ../playwright.config.ts",
"test:system": "APP_NAME=nextjs-app-v13 playwright test -c ../playwright.config.ts --project=system",
"test:visual": "PERCY_TOKEN=${PERCY_TOKEN_PIE_APERTURE_NEXT_13} npx percy exec -- wdio run ./wdio.conf.js",
"upgrade-pie-packages": "npx npm-check-updates \"@justeattakeaway/pie-*\" -u"
},
"dependencies": {
"@justeattakeaway/pie-cookie-banner": "0.19.6",
"@justeattakeaway/pie-css": "0.11.0",
"@justeattakeaway/pie-icons-webc": "0.23.1",
"@justeattakeaway/pie-webc": "0.5.3",
"@justeattakeaway/pie-webc": "0.5.6",
"@lit-labs/nextjs": "0.1.4",
"@lit/react": "1.0.2",
"next": "13.5.6",
Expand Down
5 changes: 3 additions & 2 deletions nextjs-app-v14/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@
"preview": "next start",
"lint": "next lint",
"playwright:show-report": "npx playwright show-report ../playwright-reports/nextjs-app-v14-playwright-report",
"test:system": "APP_NAME=nextjs-app-v14 playwright test -c ../playwright.config.ts",
"test:ssr": "APP_NAME=nextjs-app-v14 playwright test -c ../playwright.config.ts --project=ssr",
"test:system": "APP_NAME=nextjs-app-v14 playwright test -c ../playwright.config.ts --project=system",
"test:visual": "PERCY_TOKEN=${PERCY_TOKEN_PIE_APERTURE_NEXT_14} npx percy exec -- wdio run ./wdio.conf.js",
"upgrade-pie-packages": "npx npm-check-updates \"@justeattakeaway/pie-*\" -u"
},
"dependencies": {
"@justeattakeaway/pie-cookie-banner": "0.19.6",
"@justeattakeaway/pie-css": "0.11.0",
"@justeattakeaway/pie-icons-webc": "0.23.1",
"@justeattakeaway/pie-webc": "0.5.3",
"@justeattakeaway/pie-webc": "0.5.6",
"@lit-labs/nextjs": "0.2.0",
"@lit/react": "1.0.5",
"next": "14.2.3",
Expand Down
4 changes: 2 additions & 2 deletions nextjs-app-v14/src/app/layout/navigation.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client';

import { PieDivider } from "@justeattakeaway/pie-divider/dist/react"
import { PieLink } from "@justeattakeaway/pie-link/dist/react";
import { PieDivider } from "@justeattakeaway/pie-webc/react/divider.js"
import { PieLink } from "@justeattakeaway/pie-webc/react/link.js";
import { useRouter, usePathname } from "next/navigation";
import { type ReactNode } from "react";

Expand Down
6 changes: 3 additions & 3 deletions nuxt-app/package.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"name": "nuxt-app",
"private": true,
"type": "module",
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"playwright:show-report": "npx playwright show-report ../playwright-reports/nuxt-app-playwright-report",
"preview": "nuxt preview",
"postinstall": "nuxt prepare",
"test:system": "APP_NAME=nuxt-app npx playwright test -c ../playwright.config.ts",
"test:ssr": "APP_NAME=nuxt-app npx playwright test -c ../playwright.config.ts --project=ssr",
"test:system": "APP_NAME=nuxt-app npx playwright test -c ../playwright.config.ts --project=system",
"test:visual": "PERCY_TOKEN=${PERCY_TOKEN_PIE_APERTURE_NUXT} npx percy exec -- wdio run ./wdio.conf.js",
"upgrade-pie-packages": "npx npm-check-updates \"@justeattakeaway/pie-*\" -u"
},
Expand All @@ -24,7 +24,7 @@
"@justeattakeaway/pie-cookie-banner": "0.19.6",
"@justeattakeaway/pie-css": "0.11.0",
"@justeattakeaway/pie-icons-webc": "0.23.1",
"@justeattakeaway/pie-webc": "0.5.3",
"@justeattakeaway/pie-webc": "0.5.6",
"just-kebab-case": "4.2.0",
"nuxt-ssr-lit": "1.6.16"
},
Expand Down
9 changes: 4 additions & 5 deletions nuxt-app/test/visual/nuxt.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { waitUntilPageLoad } from '../../../webdriver-helpers/wait-helper.js';
import { percyScreenshot } from '@percy/selenium-webdriver';
const { waitForPageTitleToBe } = require('../../../webdriver-helpers/wait-helper.js');
const { percyScreenshot } = require('@percy/selenium-webdriver');

describe('Nuxt Aperture App', () => {
const pages = [
Expand All @@ -23,10 +23,9 @@ describe('Nuxt Aperture App', () => {
];

pages.forEach((page) => {
it.skip(`should navigate to the ${page.name} page.`, async () => {
it(`should navigate to the ${page.name} page.`, async () => {
await browser.url(page.url);
await waitUntilPageLoad();
await expect(await browser.getTitle()).toContain(page.name);
await waitForPageTitleToBe(page.name);
await percyScreenshot(page.name);
});
});
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"dev": "turbo run dev",
"generate": "turbo run generate --token=${TURBO_TOKEN}",
"lint": "turbo run lint --token=${TURBO_TOKEN}",
"test:ssr": "turbo run test:ssr --token=${TURBO_TOKEN} --continue",
"test:system": "turbo run test:system --token=${TURBO_TOKEN} --continue",
"playwright:show-report": "turbo run playwright:show-report",
"preview": "turbo run preview",
Expand Down
5 changes: 5 additions & 0 deletions playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ export default {
name: 'system',
use: { ...devices['Desktop Chrome'] },
testMatch: `${monorepoRoot}/test/system/**/*.spec.ts`,
},
{
name: 'ssr',
use: { ...devices['Desktop Chrome'] },
testMatch: `${monorepoRoot}/test/ssr/**/*.spec.ts`,
}
],

Expand Down
90 changes: 90 additions & 0 deletions test/ssr/ssr.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { test, expect } from '@playwright/test';
import http from 'http';
import https from 'https';
import { URL } from 'url';
import { getEnvironmentBaseUrl } from '../../playwright-helpers/configuration-helper';

const APP_NAME = process.env.APP_NAME;

const baseUrl = getEnvironmentBaseUrl(APP_NAME);

// TODO - Is there a better way to define this list?
// TODO - uncomment the components when we are ready to test them
const components = [
'assistive-text',
'button',
'card',
'checkbox',
'chip',
'cookie-banner',
'form-label',
'icon',
'icon-button',
'link',
'modal',
'spinner',
'switch',
'tag',
'text-input',
// 'notification'
];

const getComponentPageUrl = (component: string, baseUrl: string): string => `${baseUrl}/components/${component}`;

async function fetchHtml(url: string): Promise<string> {
return new Promise<string>((resolve, reject) => {
const parsedUrl = new URL(url);
const protocol = parsedUrl.protocol === 'https:' ? https : http;

protocol.get(url, (response) => {
let data = '';

response.on('data', (chunk) => {
data += chunk;
});

response.on('end', () => {
resolve(data);
});
}).on('error', (err) => {
reject(err);
});
});
}

function createComponentRegex(componentName: string): RegExp {
if (componentName === 'icon') {
return /<icon-[\w-]+[\s\S]*?<\/icon-[\w-]+>/;
}

const prefixedComponentName = `pie-${componentName}`;

return new RegExp(`<${prefixedComponentName}[\\s\\S]*?<\\/${prefixedComponentName}>`);
}

// Visit each page in the SSR apps at /components/<component> and take a snapshot of the HTML returned from the server
test.describe('SSR - Components render with shadow dom and styles', () => {
components.forEach((component) => {
test(`SSR: ${APP_NAME}: ${component}`, async () => {
// Arrange
const url = getComponentPageUrl(component, baseUrl);

// used to ensure the shadow dom markup is rendered correctly, we don't need to worry about attribute order
const shadowDomRegex = /<template\s+([^>]*shadowroot="open"[^>]*shadowrootmode="open"[^>]*|[^>]*shadowrootmode="open"[^>]*shadowroot="open"[^>]*)>/;
const styleRegex = /<style>[\s\S]*?<\/style>/;
const componentRegex = createComponentRegex(component);

// Act
const rawHtml = await fetchHtml(url);

// Extract the first <pie-[component]> element using a regular expression
const pieComponentMatch = rawHtml.match(componentRegex);
const pieComponentHtml = pieComponentMatch ? pieComponentMatch[0] : null;

// Assert
expect(pieComponentHtml).not.toBeNull();
expect(pieComponentHtml).toMatch(shadowDomRegex);
expect(pieComponentHtml).toMatch(styleRegex);
});
});
});
1 change: 0 additions & 1 deletion test/system/form.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ test.describe(`Form Page - ${process.env.APP_NAME}`, () => {
approveSettings: true,
enableNotifications: true,
newsletterSignup: true,

};

const formPage = new FormPage(page);
Expand Down
3 changes: 3 additions & 0 deletions turbo.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
"cache": false,
"dependsOn": ["build"]
},
"test:ssr": {
"cache": true
},
"test:system": {
"cache": true
},
Expand Down
4 changes: 2 additions & 2 deletions vanilla-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"build": "vite build",
"playwright:show-report": "npx playwright show-report ../playwright-reports/vanilla-app-playwright-report",
"preview": "vite preview",
"test:system": "APP_NAME=vanilla-app npx playwright test --config=../playwright.config.ts",
"test:system": "APP_NAME=vanilla-app npx playwright test --config=../playwright.config.ts --project=system",
"test:visual": "PERCY_TOKEN=${PERCY_TOKEN_PIE_APERTURE_VANILLA} npx percy exec -- wdio run ./wdio.conf.js",
"upgrade-pie-packages": "npx npm-check-updates \"@justeattakeaway/pie-*\" -u"
},
Expand All @@ -21,7 +21,7 @@
"@justeattakeaway/pie-cookie-banner": "0.19.6",
"@justeattakeaway/pie-css": "0.11.0",
"@justeattakeaway/pie-icons-webc": "0.23.1",
"@justeattakeaway/pie-webc": "0.5.3"
"@justeattakeaway/pie-webc": "0.5.6"
},
"installConfig": {
"hoistingLimits": "workspaces"
Expand Down
Loading

0 comments on commit e4d4ae5

Please sign in to comment.