Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: UI tests with playwright - HTML around and in web component #31

Merged
merged 13 commits into from
Jul 13, 2024
16 changes: 15 additions & 1 deletion .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ on:

jobs:
build:
name: Build and Test 🛠️ 🧪

runs-on: ubuntu-latest

# Ref: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs#example-using-npm
Expand All @@ -24,4 +26,16 @@ jobs:
- name: Install dependencies
run: npm install
- run: npm run build --if-present
- run: npm test
- name: Run unit tests 🧪 🚀 ⚛️
run: npm run test
- name: Install Playwright Browsers 🧪 🐣
run: npx playwright install --with-deps
- name: Run Playwright tests 🧪 🚀 🖼️
run: npm run test-ui
- name: Upload Playwright report 🧪 📝
uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: playwright-report/
retention-days: 3
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/node_modules
public/build
package-lock.json

# Tests
/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/
26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,31 @@ Format the code

### Test app

`npm run test`
Unit tests

```bash
npm run test
```

UI tests

- Precondition: Install browsers for UI tests

```bash
npx playwright install --with-deps
```

Run tests headless mode

```bash
npm run test-ui
```

Interactive mode

```bash
npm run test-ui -- --ui
```

### Run app 🚀

Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,20 @@
"build": "node build.js",
"prettier": "prettier . --write",
"start": "node dev-server.js",
"test": "node --test"
"test": "node --test",
"test-ui": "playwright test"
},
"author": "",
"license": "MIT",
"description": "",
"devDependencies": {
"@fastify/static": "7.0.4",
"@playwright/test": "^1.45.1",
"@rollup/plugin-commonjs": "26.0.1",
"@rollup/plugin-node-resolve": "15.2.3",
"@rollup/plugin-replace": "5.0.7",
"@rollup/plugin-terser": "0.4.4",
"@types/node": "^20.14.10",
"fastify": "4.28.0",
"prettier": "3.3.2",
"rollup": "4.18.0"
Expand Down
79 changes: 79 additions & 0 deletions playwright.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { defineConfig, devices } from "@playwright/test";

/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
// require('dotenv').config({ path: path.resolve(__dirname, '.env') });

/**
* @see https://playwright.dev/docs/test-configuration
*/
const config = defineConfig({
testDir: "./test-ui",
/* Run tests in files in parallel */
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: "html",
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
baseURL: "http://127.0.0.1:4000",

/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: "on-first-retry",
},

/* Configure projects for major browsers */
projects: [
{
name: "chromium",
use: { ...devices["Desktop Chrome"] },
},

{
name: "firefox",
use: { ...devices["Desktop Firefox"] },
},

{
name: "webkit",
use: { ...devices["Desktop Safari"] },
},

/* Test against mobile viewports. */
{
name: "Mobile Chrome",
use: { ...devices["Pixel 5"] },
},
{
name: "Mobile Safari",
use: { ...devices["iPhone 12"] },
},

/* Test against branded browsers. */
// {
// name: 'Microsoft Edge',
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
// },
// {
// name: 'Google Chrome',
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
// },
],

/* Run your local dev server before starting the tests */
webServer: {
command: "npm run start",
url: "http://127.0.0.1:4000",
reuseExistingServer: !process.env.CI,
},
});

export default config;
8 changes: 5 additions & 3 deletions public/index.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<html>
<head>
<title>Home</title>
<title>Alpaca Map Web Component inside this page</title>
<style>
.external-website-container {
background-color: lightgray;
Expand All @@ -20,7 +20,9 @@
<body>
<div class="external-website-container">
<h1>Alpaca Map web component - index.html page header</h1>
<p>This is the external website content</p>
<p>
This is the external website which has content ABOVE the web component.
</p>
<p>It contains some info then shows the web component below</p>
<!--
// USAGE Step 2 - START
Expand All @@ -35,7 +37,7 @@ <h1>Alpaca Map web component - index.html page header</h1>
-->

<p>
This is the external website which has content below the web component.
This is the external website which has content BELOW the web component.
</p>
</div>

Expand Down
10 changes: 8 additions & 2 deletions src/alpaca-map.js
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,10 @@ export default class AlpacaMap extends LitElement {
</div>
<footer class="footer-container">
<div>
<a href="https://www.alpaca.life" target="_blank"
<a
href="https://www.alpaca.life"
target="_blank"
data-testid="link-logo"
><img
src="/assets/images/alpaca.life.logo.png"
width="100px"
Expand All @@ -429,7 +432,10 @@ export default class AlpacaMap extends LitElement {
>
</div>
<div>
<a href="https://ko-fi.com/anitalipsky" target="_blank"
<a
href="https://ko-fi.com/anitalipsky"
target="_blank"
data-testid="link-support"
><img
id="ko-fi"
src="/assets/images/kofi_bg_tag_white.svg"
Expand Down
90 changes: 90 additions & 0 deletions test-ui/index.html.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { test, expect } from "@playwright/test";

test.beforeEach(async ({ page }) => {
// ARRANGE
await page.goto("/");
});

test.describe("Content around the web component", () => {
test("title", async ({ page }) => {
// ASSERT
await expect(page).toHaveTitle(/Alpaca Map Web Component inside this page/);
});

test("page containing web component", async ({ page }) => {
// ASSERT
await page
.getByText(
"This is the external website which has content ABOVE the web component."
)
.isVisible();
});
});

test.describe("Web component within page", () => {
test("checkboxes - defaults", async ({ page }) => {
// ASSERT
await expect(page.getByLabel("Public farms")).toBeChecked({
checked: true,
});
await expect(page.getByLabel("Private farms")).toBeChecked({
checked: true,
});
await expect(page.getByLabel("Alpaca sales")).toBeChecked({
checked: false,
});
await expect(page.getByLabel("Alpaca walking")).toBeChecked({
checked: false,
});
await expect(page.getByLabel("Bookable")).toBeChecked({
checked: false,
});
await expect(page.getByLabel("Shop")).toBeChecked({
checked: false,
});
await expect(page.getByLabel("Overnight stay")).toBeChecked({
checked: false,
});
await expect(page.getByLabel("Stud services")).toBeChecked({
checked: false,
});
});

test("header element", async ({ page }) => {
// ASSERT
await page.locator("header").isVisible();
});

test("footer element", async ({ page }) => {
// ASSERT
await page.locator("footer").isVisible();

const logo = page.getByAltText("Alpaca Life logo");
await expect(logo).toBeVisible();

const linkLogo = page.getByTestId("link-logo");
await expect(linkLogo).toHaveAttribute("href", "https://www.alpaca.life");

const linkWebPage = page.getByRole("link", { name: "www.alpaca.life" });
await expect(linkWebPage).toHaveAttribute(
"href",
"https://www.alpaca.life"
);
await expect(linkWebPage).toBeVisible();

const logoSupport = page.getByAltText("Buy me a ko-fi");
await expect(logoSupport).toBeVisible();

const linkLogoSupport = page.getByTestId("link-support");
await expect(linkLogoSupport).toHaveAttribute(
"href",
"https://ko-fi.com/anitalipsky"
);

await page
.getByText(
"This is the external website which has content BELOW the web component."
)
.isVisible();
});
});