Skip to content

Commit

Permalink
feat: add playwright (#4337)
Browse files Browse the repository at this point in the history
* add playwright harness script and configs (#4229)

* split harness and server

* add environment variables
* fix tsconfig conflicts
* add README

* update yarn.lock after rebase

* install playwright latest

* Replace rollup-plugin-copy with copyfiles

* cross-env environment var setting

* add playwright CI

* add ci-workflow to linux machine

* add playwright ci to linux environment

* work flow fixes in linux

* resolve conflict issue

* playwright worflow

* playwright workflow

* fix run workflow

* install playwright for servers

* change tittle for the build

* Update .github/workflows/ci-weekly.yml

Co-authored-by: Jane Chu <7559015+janechu@users.noreply.github.com>

* Update build/copy.js

Co-authored-by: Jane Chu <7559015+janechu@users.noreply.github.com>

* remove blank lines

* renaming test dir to __test__

* organize gitignore files

* Update packages/web-components/fast-components/__test__/README.md

* fix environment variable casing

* remove abbreviation from environment variable

* sort package.json scripts

Co-authored-by: John Kreitlow <863023+radium-v@users.noreply.github.com>
Co-authored-by: John Kreitlow <john.kreitlow@microsoft.com>
Co-authored-by: nicholasrice <nicholasrice@users.noreply.github.com>
Co-authored-by: Ibrahim Maga <imaga75@hotmail.com>
Co-authored-by: Jane Chu <7559015+janechu@users.noreply.github.com>
  • Loading branch information
6 people authored Feb 18, 2021
1 parent b2f2f29 commit be996ee
Show file tree
Hide file tree
Showing 22 changed files with 883 additions and 125 deletions.
39 changes: 36 additions & 3 deletions .github/workflows/ci-weekly.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
name: CI - FAST Validation

on:
push:
branches:
- master
- releases/*
pull_request:
branches:
- master
- releases/*
- features/*
schedule:
- cron: 0 7 * * 3

jobs:
build_linux:
linux_cross-platform_cross-browser:
runs-on: [ubuntu-latest]

steps:
Expand Down Expand Up @@ -36,6 +45,14 @@ jobs:
- name: Testing unit tests
run: yarn lerna run test --stream

- name: Test Playwright
run: |
cd packages/web-components/fast-components
npm install playwright
yarn test-chromium:pw
yarn test-firefox:pw
yarn test-webkit:pw
- name: Collect and upload code coverage to Code Climate
uses: paambaati/codeclimate-action@v2.6.0

Expand All @@ -55,7 +72,7 @@ jobs:
${{github.workspace}}/sites/fast-component-explorer/coverage/lcov.info:lcov
debug: false

build-windows:
windows_cross-platform_cross-browser:
runs-on: [windows-latest]

steps:
Expand Down Expand Up @@ -94,6 +111,14 @@ jobs:

- name: Testing unit tests
run: yarn lerna run test --stream

- name: Test Playwright
run: |
cd packages/web-components/fast-components
npm install playwright
yarn test-chromium:pw
yarn test-firefox:pw
yarn test-webkit:pw
- name: Collect and upload code coverage to Code Climate
uses: paambaati/codeclimate-action@v2.6.0
Expand All @@ -114,7 +139,7 @@ jobs:
${{github.workspace}}/sites/fast-component-explorer/coverage/lcov.info:lcov
debug: false

build-macos:
macos_cross-platform_cross-browser:
runs-on: [macos-latest]

steps:
Expand Down Expand Up @@ -145,6 +170,14 @@ jobs:
- name: Testing unit tests
run: yarn lerna run test --stream

- name: Test Playwright
run: |
cd packages/web-components/fast-components
npm install playwright
yarn test-chromium:pw
yarn test-firefox:pw
yarn test-webkit:pw
- name: Collect and upload code coverage to Code Climate
uses: paambaati/codeclimate-action@v2.6.0

Expand Down
22 changes: 22 additions & 0 deletions build/copy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* eslint-env node, es2015 */
/* eslint-disable @typescript-eslint/explicit-function-return-type, @typescript-eslint/no-var-requires, @typescript-eslint/typedef */
const copyfiles = require("copyfiles");

function copy(files, destination, config = { flat: true, verbose: true, up: true }) {
return new Promise((resolve, reject) => {
return copyfiles([...files, destination], config, err =>
err ? reject(err.details) : resolve()
);
}).catch(err => {
console.error(err);
process.exit(1);
});
}

/**
* Copy files from one place to another.
* @param {string[]} files - Paths and globs to copy
* @param {string} destination - Directory to copy the files to
* @param {{ flat?: boolean; verbose?: boolean; up?: boolean; }} config - Configuration options passed to `copyfiles`.
*/
module.exports = copy;
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
"**/@types/chai",
"**/@types/jest",
"**/@types/karma",
"**/@types/mocha"
"**/@types/mocha",
"**/@types/node",
"**/chai"
]
},
"repository": {
Expand Down Expand Up @@ -121,6 +123,7 @@
"@types/node": "^9.4.7",
"beachball": "^1.36.2",
"chalk": "^2.4.2",
"copyfiles": "^2.4.1",
"docusaurus-init": "^1.11.0",
"dotenv": "^6.0.0",
"eyes.selenium": "3.6.2",
Expand All @@ -138,6 +141,7 @@
"yargs": "^11.0.0"
},
"dependencies": {
"playwright": "^1.8.0",
"saucelabs": "^1.5.0",
"selenium-webdriver": "^3.6.0"
}
Expand Down
4 changes: 3 additions & 1 deletion packages/web-components/fast-components/.gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
.rollupcache
coverage
tsdoc-metadata.json
temp
temp
__test__/dist
__test__/public
10 changes: 10 additions & 0 deletions packages/web-components/fast-components/__test__/.mocharc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"colors": true,
"recursive": true,
"timeout": 5000,
"require": [
"esm",
"./__test__/server.js",
"./__test__/harness.js"
]
}
62 changes: 62 additions & 0 deletions packages/web-components/fast-components/__test__/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# FAST Components Test Harness

## Core Concepts

The general workflow for running functional tests with Playwright:

1. Build `*.pw.spec.ts` files with `tsc`, output to `dist/`. These are the files that Mocha will run directly.
2. Build fixtures and distribution files with `rollup`, ouptut to `public/`, so Playwright can navigate to them in the browser.
3. Run Mocha:
* Before running any tests, start a local server to host the fixtures. This can be skipped for CI environments (see the "Environment Variables" section below).
* Before starting the test suite, open the browser with Playwright.
* Before each test, open a new page in the browser and navigate to a hosted fixture. After each test, close the page.
* After all tests complete, close the browser and stop the local server.

The test harness for FAST Components is composed of these parts:

* `server.js` - Uses [Mocha Global setup fixtures](https://mochajs.org/#global-setup-fixtures) for starting a local web server before running any tests. This is needed so Playwright has pages it can navigate to, where tests can inject their scenarios. The web server is closed after all the tests have run.
* `harness.js` - Uses [Mocha root hook plugins](https://mochajs.org/#root-hook-plugins) for ensuring the Playwright browser instance is launched and that a new page is opened before every test, and closed after each test completes.

Both `server.js` and `harness.js` are included as `require` entries in `.mocharc.json`.

## CLI

### Standard commands

|command|description|
|-|-|
| `yarn clean:test` | Remove `dist/` and `public/` from previous builds. |
| `yarn build:pw-tests` | Build `*.pw.spec.ts` files with `tsc` (outputs to `dist/`). |
| `yarn build:pw-fixtures` | Build fixtures and distribution files with `rollup` (ouptuts to `public/`). |
| `yarn build:pw` | Run `build:pw-tests` and `build:pw-fixtures`. |
| `yarn test-pw` | Run all built tests with Mocha. The default browser is `chromium`. |
| `yarn test-pw:full` | Run `clean:test`, `build:pw`, and `test-pw`. |
| `yarn test-chromium:pw` | Run `test-pw:full` in Chromium. |
| `yarn test-firefox:pw` | Run `test-pw:full` in Firefox. |
| `yarn test-webkit:pw` | Run `test-pw:full` in Webkit. |

### Environment Variables

| variable | description |
|-|-|
| `PLAYWRIGHT_BROWSER` | Target a specific Playwright browser. Values are `chromium`, `firefox`, and `webkit`. |
| `FIXTURE` | Override the fixture file that Playwright will use for all tests. Values depend on available fixtures in `fixtures/`, currently `index.html` or `iife.html`. Defaults to `index.html`. |
| `FIXTURE_URL` | Override the entire fixture URL that Playwright will use for all tests. Defaults to `http://localhost:7001/index.html`. |
| `USE_LOCAL` | When set to `false`, the local Express server initialization will be skipped. |
| `PORT` | Override the listening port for Express. Defaults to `7001`. |

### Examples

* Run all tests against a specific website:

```bash
USE_LOCAL=false \
FIXTURE_URL=http://explore.fast.design/preview \
yarn test-pw:full
```

* Re-run the tests in a different browser, without rebuilding everything:

```bash
PLAYWRIGHT_BROWSER=firefox yarn test-pw
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>FAST Components Test Harness</title>
<script src="/fast-components.iife.js"></script>
</head>
<body>
<fast-design-system-provider id="root" use-defaults></fast-design-system-provider>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>FAST Components Test Harness</title>
<script src="/fast-components.js" type="module"></script>
</head>
<body>
<fast-design-system-provider id="root" use-defaults></fast-design-system-provider>
</body>
</html>
33 changes: 33 additions & 0 deletions packages/web-components/fast-components/__test__/harness.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* eslint-env node */
import { chromium, firefox, webkit } from "playwright";

const selectedBrowser = process.env.PW_BROWSER || "chromium";
const FixtureURL = process.env.FIXTURE_URL;
const fixture = process.env.FIXTURE || "index.html";
const expressPort = process.env.PW_PORT || 7001;

export const mochaHooks = {
async beforeAll() {
const browser = { chromium, firefox, webkit }[selectedBrowser];
this.browser = await browser.launch();
console.log(`Launched ${selectedBrowser} browser`);
},

async beforeEach() {
this.page = await this.browser.newPage();
const fixtureUrl = FixtureURL || `http://localhost:${expressPort}/${fixture}`;
await this.page.goto(fixtureUrl);
},

async afterEach() {
if (this.page) {
await this.page.close();
}
},

async afterAll() {
if (this.browser) {
await this.browser.close();
}
},
};
54 changes: 54 additions & 0 deletions packages/web-components/fast-components/__test__/rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/* eslint-env node */
/* eslint-disable @typescript-eslint/no-var-requires */

import path from "path";
import commonJS from "rollup-plugin-commonjs";
import resolve from "rollup-plugin-node-resolve";
import typescript from "rollup-plugin-typescript2";

const copy = require("../../../../build/copy");

const srcDir = path.resolve(__dirname, "..", "src");
const distDir = path.resolve(__dirname, "public");

export default [
{
context: "this",
input: path.resolve(srcDir, "index-rollup.ts"),
onwarn(warning, warn) {
// The IIFE export doesn't have a namespace since component exports
// are expected to be top-level objects
if (warning.code === "MISSING_NAME_OPTION_FOR_IIFE_EXPORT") {
return;
}

warn(warning);
},
output: [
{
file: path.resolve(distDir, "fast-components.js"),
format: "esm",
sourcemap: true,
},
{
file: path.resolve(distDir, "fast-components.iife.js"),
format: "iife",
sourcemap: true,
},
],
plugins: [
resolve(),
commonJS(),
typescript({
tsconfigOverride: {
compilerOptions: {
declaration: false,
},
},
}),
],
},
];

// Copy the fixtures to the public directory
copy([`${path.resolve(__dirname, "fixtures")}/*`], distDir);
36 changes: 36 additions & 0 deletions packages/web-components/fast-components/__test__/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* eslint-env node */
import path from "path";
import express from "express";

const useLocalServer = process.env.USE_LOCAL !== "false";
const expressPort = process.env.PORT || 7001;

let server;

const app = useLocalServer && express();

if (app) {
app.use(express.static(path.resolve(__dirname, "public")));
}

export function mochaGlobalSetup() {
if (!useLocalServer) {
console.log("Test harness server skipped.");
return;
}

server = app.listen(expressPort, () => {
console.log(`Test harness server listening on port ${expressPort}`);
});
}

export async function mochaGlobalTeardown() {
if (!useLocalServer) {
return;
}

if (server) {
await server.close();
console.log(`Test harness server on port ${expressPort} closed`);
}
}
15 changes: 15 additions & 0 deletions packages/web-components/fast-components/__test__/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"declaration": false,
"declarationDir": null,
"target": "ES2017",
"outDir": "dist",
"importsNotUsedAsValues": "preserve",
"types": [
"mocha",
"node"
],
},
"include": ["../src/**/*.pw.spec.ts"]
}
Loading

0 comments on commit be996ee

Please sign in to comment.