Skip to content

Commit

Permalink
integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dwightjack committed Apr 18, 2023
1 parent 5a30c79 commit 72012f0
Show file tree
Hide file tree
Showing 8 changed files with 286 additions and 2 deletions.
23 changes: 22 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ on: [push]
jobs:
lint_and_build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: pnpm/action-setup@v2
Expand All @@ -17,3 +16,25 @@ jobs:
- run: pnpm i --frozen-lockfile
- run: pnpm run lint
- run: pnpm run build
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: pnpm/action-setup@v2
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version-file: '.node-version'
cache: 'pnpm'
- run: pnpm i --frozen-lockfile
- name: Install Playwright Browsers
run: pnpm exec playwright install chromium --with-deps
- name: Run Playwright tests
run: pnpm exec playwright test
- uses: actions/upload-artifact@v3
if: always()
with:
name: playwright-report
path: playwright-report/
retention-days: 10
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,6 @@ dist

# Local Netlify folder
.netlify
/test-results/
/playwright-report/
/playwright/.cache/
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,17 @@
"dev": "netlify dev -c \"pnpm exec vite\"",
"build": "pnpm run lint && vite build",
"preview": "netlify dev -d dist",
"lint": "eslint && stylelint --aei '**/*.css'"
"lint": "eslint && stylelint --aei '**/*.css'",
"test": "playwright test"
},
"devDependencies": {
"@playwright/test": "^1.32.3",
"@types/node": "^18.15.11",
"eslint": "8.38.0",
"eslint-config-prettier": "8.8.0",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-prettier": "4.2.1",
"mockdate": "^3.0.5",
"netlify-cli": "13.2.2",
"prettier": "2.8.7",
"stylelint": "15.5.0",
Expand Down
48 changes: 48 additions & 0 deletions playwright.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// @ts-check
const { defineConfig, devices } = require('@playwright/test');

/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
// require('dotenv').config();

/**
* @see https://playwright.dev/docs/test-configuration
*/
module.exports = defineConfig({
testDir: './tests',
/* 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://localhost:8888',

/* 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'] },
},
],

/* Run your local dev server before starting the tests */
webServer: {
command: 'pnpm exec vite --port=8888',
url: 'http://localhost:8888',
reuseExistingServer: !process.env.CI,
},
});
25 changes: 25 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions tests/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"root": true,
"extends": ["eslint:recommended", "plugin:prettier/recommended"],
"env": {
"node": true,
"es6": true,
"browser": true
},
"parserOptions": {
"ecmaVersion": 2020,
"sourceType": "module"
},
"globals": { "YUI": true },
"rules": {
"no-shadow": "warn",
"block-scoped-var": "error",
"consistent-return": "error",
"eqeqeq": "error"
}
}
115 changes: 115 additions & 0 deletions tests/app.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// @ts-check
import { test, expect } from '@playwright/test';
import zones from './fixtures/zones';

/**
* @param {import('@playwright/test').Page} page
* @param {string} name
* @returns {import('@playwright/test').Locator}
*/
function getCard(page, name) {
return page.locator('article', {
has: page.getByRole('heading', { name }),
});
}

test.beforeEach(async ({ page, context }) => {
await page.route('/api/tzlist', async (route) => {
const json = {
zones,
};
await route.fulfill({ json });
});
await context.addInitScript({
path: require.resolve('mockdate'),
});
await context.addInitScript(() => {
window.MockDate.set('2022-08-03T00:00:00+09:00');
});
await page.goto('/');
});

test.describe('startup', () => {
test.use({ timezoneId: 'Asia/Tokyo' });
test('Automatically add current timezone card', async ({ page }) => {
const card = await getCard(page, 'Asia/Tokyo');
await expect(card).toBeVisible();
});

test('Automatically sets the current date', async ({ page }) => {
const date = getCard(page, 'Asia/Tokyo').getByLabel('Date');
await expect(date).toHaveAttribute('type', 'date');
await expect(date).toHaveValue('2022-08-03');
});

test('Automatically sets the current time', async ({ page }) => {
const time = getCard(page, 'Asia/Tokyo').getByLabel('Time');
await expect(time).toHaveValue('00:00');
});

test('Has an auto-complete list of zones', async ({ page }) => {
await expect(page.locator('datalist > option')).toHaveCount(zones.length);
for (const { name } of zones) {
await expect(
page.locator(`datalist > option[value="${name}"]`),
).toHaveCount(1);
}
});
});

test.describe('interactions', () => {
test.use({ timezoneId: 'Asia/Tokyo' });
test.beforeEach(async ({ page }) => {
await page
.getByPlaceholder('Add a new timezone...')
.type('Europe/Helsinki');
await page.getByRole('button', { name: 'Add' }).click();
});
test('Add Europe/Helsinki time card', async ({ page }) => {
const card = await getCard(page, 'Europe/Helsinki');
await expect(card).toBeVisible();
await expect(card.getByLabel('Date')).toHaveValue('2022-08-02');
await expect(card.getByLabel('Time')).toHaveValue('18:00');
});

test('Added cards do not show in autocomplete', async ({ page }) => {
const option = page.locator('datalist > option[value="Europe/Helsinki"]');
await expect(option).toBeDisabled();
});

test('Remove Europe/Helsinki time card', async ({ page }) => {
const card = await getCard(page, 'Europe/Helsinki');
await card.getByRole('button', { name: 'Remove' }).click();
await expect(getCard(page, 'Europe/Helsinki')).not.toBeVisible();

await expect(
page.locator('datalist > option[value="Europe/Helsinki"]'),
).toBeEnabled();
});

test('Changes to the date of one card updates other cards', async ({
page,
}) => {
const tokyoCard = await getCard(page, 'Asia/Tokyo');
const helsinkiCard = await getCard(page, 'Europe/Helsinki');

await tokyoCard.getByLabel('Date').fill('2023-07-02');
await expect(helsinkiCard.getByLabel('Date')).toHaveValue('2023-07-01');

await helsinkiCard.getByLabel('Date').fill('2023-07-10');
await expect(tokyoCard.getByLabel('Date')).toHaveValue('2023-07-11');
});

test('Changes to the time of one card updates other cards', async ({
page,
}) => {
const tokyoCard = await getCard(page, 'Asia/Tokyo');
const helsinkiCard = await getCard(page, 'Europe/Helsinki');

await tokyoCard.getByLabel('Time').fill('09:00');
await expect(helsinkiCard.getByLabel('Time')).toHaveValue('03:00');

await helsinkiCard.getByLabel('Time').fill('23:00');
await expect(tokyoCard.getByLabel('Time')).toHaveValue('05:00');
});
});
49 changes: 49 additions & 0 deletions tests/fixtures/zones.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
export default [
{
name: 'Europe/Helsinki',
alternativeName: 'Eastern European Time',
group: ['Europe/Helsinki', 'Europe/Mariehamn'],
continentCode: 'EU',
continentName: 'Europe',
countryName: 'Finland',
countryCode: 'FI',
mainCities: ['Helsinki', 'Espoo', 'Tampere', 'Oulu'],
rawOffsetInMinutes: 120,
abbreviation: 'EET',
rawFormat: '+02:00 Eastern European Time - Helsinki, Espoo, Tampere, Oulu',
currentTimeOffsetInMinutes: 180,
currentTimeFormat:
'+03:00 Eastern European Time - Helsinki, Espoo, Tampere, Oulu',
},
{
name: 'Asia/Tokyo',
alternativeName: 'Japan Time',
group: ['Asia/Tokyo', 'Japan'],
continentCode: 'AS',
continentName: 'Asia',
countryName: 'Japan',
countryCode: 'JP',
mainCities: ['Tokyo', 'Yokohama', 'Osaka', 'Nagoya'],
rawOffsetInMinutes: 540,
abbreviation: 'JST',
rawFormat: '+09:00 Japan Time - Tokyo, Yokohama, Osaka, Nagoya',
currentTimeOffsetInMinutes: 540,
currentTimeFormat: '+09:00 Japan Time - Tokyo, Yokohama, Osaka, Nagoya',
},
{
name: 'Asia/Dhaka',
alternativeName: 'Bangladesh Time',
group: ['Asia/Dhaka', 'Asia/Dacca'],
continentCode: 'AS',
continentName: 'Asia',
countryName: 'Bangladesh',
countryCode: 'BD',
mainCities: ['Dhaka', 'Chattogram', 'Khulna', 'Rangpur'],
rawOffsetInMinutes: 360,
abbreviation: 'BST',
rawFormat: '+06:00 Bangladesh Time - Dhaka, Chattogram, Khulna, Rangpur',
currentTimeOffsetInMinutes: 360,
currentTimeFormat:
'+06:00 Bangladesh Time - Dhaka, Chattogram, Khulna, Rangpur',
},
];

0 comments on commit 72012f0

Please sign in to comment.