Skip to content

Commit fe26525

Browse files
committed
More E2E test improvements
1 parent 314473f commit fe26525

24 files changed

+124
-141
lines changed

.github/workflows/deploy-production.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,8 @@ jobs:
155155
project-name: 'Thunderbird Appointment'
156156
build-name: 'Production Deployment Tests: BUILD_INFO'
157157

158-
- name: Run Playwright Tests on Browserstack
158+
- name: Production Sanity E2E Tests on Desktop Firefox
159159
run: |
160160
cd ./test/e2e
161161
cp .env.prod.example .env
162-
npm run prod-sanity-test-browserstack-gha
162+
npm run prod-sanity-test-browserstack-firefox

.github/workflows/deploy-staging.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,9 +262,8 @@ jobs:
262262
project-name: 'Thunderbird Appointment'
263263
build-name: 'E2E Tests: BUILD_INFO'
264264

265-
- name: Run E2E Tests on stage via Browserstack
265+
- name: Stage E2E Tests on Desktop Firefox
266266
run: |
267267
cd ./test/e2e
268268
cp .env.stage.example .env
269-
npm run e2e-test-browserstack-gha
270-
269+
npm run e2e-test-browserstack-firefox

.github/workflows/nightly-tests-desktop.yml

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ permissions:
1515
contents: read # This is required for actions/checkout
1616

1717
jobs:
18-
prod-sanity-browserstack:
19-
name: prod-sanity-browserstack
18+
nightly-prod-desktop-e2e:
19+
name: nightly-prod-desktop-e2e
2020
runs-on: ubuntu-latest
2121
environment: production
2222
env:
@@ -47,10 +47,26 @@ jobs:
4747
project-name: 'Thunderbird Appointment'
4848
build-name: 'TB Appointment Nightly Tests (Desktop): BUILD_INFO'
4949

50-
- name: Run E2E Tests on Production on Browserstack (Desktop)
50+
- name: Prod E2E Tests on Desktop Firefox
5151
# don't send GHA failure email if any of the E2E tests fail, can be annoying (I check the jobs each day in BrowserStack)
5252
continue-on-error: true
5353
run: |
5454
cd ./test/e2e
5555
cp .env.prod.example .env
56-
npm run prod-nightly-tests-browserstack-gha
56+
npm run prod-nightly-tests-browserstack-firefox
57+
58+
- name: Prod E2E Tests on Desktop Safari Webkit
59+
# don't send GHA failure email if any of the E2E tests fail, can be annoying (I check the jobs each day in BrowserStack)
60+
continue-on-error: true
61+
run: |
62+
cd ./test/e2e
63+
cp .env.prod.example .env
64+
npm run prod-nightly-tests-browserstack-safari
65+
66+
- name: Prod E2E Tests on Desktop Chromium
67+
# don't send GHA failure email if any of the E2E tests fail, can be annoying (I check the jobs each day in BrowserStack)
68+
continue-on-error: true
69+
run: |
70+
cd ./test/e2e
71+
cp .env.prod.example .env
72+
npm run prod-nightly-tests-browserstack-chromium

.github/workflows/nightly-tests-mobile.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ permissions:
1515
contents: read # This is required for actions/checkout
1616

1717
jobs:
18-
prod-nightly-mobile-browserstack:
19-
name: prod-nighlty-mobile-browserstack
18+
nightly-prod-mobile-e2e:
19+
name: nightly-prod-mobile-e2e
2020
runs-on: ubuntu-latest
2121
environment: production
2222
env:
@@ -53,4 +53,4 @@ jobs:
5353
run: |
5454
cd ./test/e2e
5555
cp .env.prod.example .env
56-
npm run prod-nightly-tests-mobile-browserstack-gha
56+
npm run prod-nightly-tests-mobile-browserstack-android-chrome

test/e2e/browserstack-desktop-nightly.yml

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ platforms:
4444
playwrightConfigOptions:
4545
name: Safari-OSX
4646
setup:
47-
- name: 'setup_safari_osx'
47+
- name: 'setup_webkit'
4848
testMatch: 'auth.desktop.setup.ts'
4949
use:
5050
storageState: 'test-results/.auth/user.json'
@@ -56,19 +56,7 @@ platforms:
5656
playwrightConfigOptions:
5757
name: Chromium-Win11
5858
setup:
59-
- name: 'setup_chromium_win'
60-
testMatch: 'auth.desktop.setup.ts'
61-
use:
62-
storageState: 'test-results/.auth/user.json'
63-
64-
- os: Windows
65-
osVersion: 11
66-
browserName: edge
67-
browserVersion: latest
68-
playwrightConfigOptions:
69-
name: Edge-Win11
70-
setup:
71-
- name: 'setup_edge_win'
59+
- name: 'setup_chromium'
7260
testMatch: 'auth.desktop.setup.ts'
7361
use:
7462
storageState: 'test-results/.auth/user.json'

test/e2e/package.json

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@
55
"scripts": {
66
"e2e-test": "npx playwright test --grep e2e-suite --project=firefox",
77
"e2e-test-headed": "npx playwright test --grep e2e-suite --project=firefox --headed",
8-
"e2e-test-browserstack": "npx browserstack-node-sdk playwright test --grep e2e-suite --browserstack.buildName 'Appointment E2E Tests (Desktop)' --browserstack.config 'browserstack-desktop.yml'",
9-
"e2e-test-browserstack-gha": "npx browserstack-node-sdk playwright test --grep e2e-suite --project=Firefox-OSX --browserstack.config 'browserstack-desktop.yml'",
8+
"e2e-test-browserstack-firefox": "npx browserstack-node-sdk playwright test --grep e2e-suite --project=Firefox-OSX --browserstack.config 'browserstack-desktop.yml'",
109
"prod-sanity-test": "npx playwright test --grep prod-sanity --project=firefox",
1110
"prod-sanity-test-headed": "npx playwright test --grep prod-sanity --project=firefox --headed",
12-
"prod-sanity-test-browserstack": "npx browserstack-node-sdk playwright test --grep prod-sanity --project=Firefox-OSX --browserstack.buildName 'Production Sanity Test (Desktop)' --browserstack.config 'browserstack-desktop.yml'",
13-
"prod-sanity-test-browserstack-gha": "npx browserstack-node-sdk playwright test --grep prod-sanity --project=Firefox-OSX --browserstack.config 'browserstack-desktop.yml'",
14-
"prod-nightly-tests-browserstack-gha": "npx browserstack-node-sdk playwright test --grep prod-nightly --browserstack.config 'browserstack-desktop-nightly.yml'",
15-
"e2e-test-mobile-browserstack": "npx browserstack-node-sdk playwright test --grep e2e-mobile-suite --browserstack.buildName 'Appointment E2E Tests (Mobile)' --browserstack.config 'browserstack-mobile.yml'",
16-
"prod-nightly-tests-mobile-browserstack-gha": "npx browserstack-node-sdk playwright test --grep prod-mobile-nightly --browserstack.config 'browserstack-mobile-nightly.yml'",
11+
"prod-sanity-test-browserstack-firefox": "npx browserstack-node-sdk playwright test --grep prod-sanity --project=Firefox-OSX --browserstack.buildName 'Appointment Production Sanity Test (Desktop)' --browserstack.config 'browserstack-desktop.yml'",
12+
"prod-nightly-tests-browserstack-firefox": "npx browserstack-node-sdk playwright test --grep prod-nightly --project=Firefox-OSX --browserstack.buildName 'Appointment Nightly Tests Firefox Desktop' --browserstack.config 'browserstack-desktop-nightly.yml'",
13+
"prod-nightly-tests-browserstack-safari": "npx browserstack-node-sdk playwright test --grep prod-nightly --project=Safari-OSX --browserstack.buildName 'Appointment Nightly Tests Safari Desktop' --browserstack.config 'browserstack-desktop-nightly.yml'",
14+
"prod-nightly-tests-browserstack-chromium": "npx browserstack-node-sdk playwright test --grep prod-nightly --project=Chromium-Win11 --browserstack.buildName 'Appointment Nightly Tests Chromium Desktop' --browserstack.config 'browserstack-desktop-nightly.yml'",
15+
"prod-nightly-tests-mobile-browserstack-android-chrome": "npx browserstack-node-sdk playwright test --grep prod-mobile-nightly --project=Chrome-GooglePixel10 --browserstack.buildName 'Appointment Nightly Tests Android Chrome' --browserstack.config 'browserstack-mobile-nightly.yml'",
1716
"postinstall": "npm update browserstack-node-sdk"
1817
},
1918
"keywords": [],

test/e2e/pages/availability-page.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ import { expect, type Page, type Locator } from '@playwright/test';
22

33
import {
44
APPT_AVAILABILITY_PAGE,
5+
APPT_TIMEZONE_SETTING_PRIMARY,
56
TIMEOUT_1_SECOND,
67
TIMEOUT_3_SECONDS,
7-
APPT_TIMEZONE_SETTING_PRIMARY,
8+
TIMEOUT_10_SECONDS,
89
TIMEOUT_30_SECONDS,
910
} from '../const/constants';
1011

@@ -93,7 +94,7 @@ export class AvailabilityPage {
9394
async gotoAvailabilityPage() {
9495
// go to availability page, sometimes takes a bit to load all element values!
9596
await this.page.goto(APPT_AVAILABILITY_PAGE, { timeout: TIMEOUT_30_SECONDS });
96-
await this.page.waitForTimeout(TIMEOUT_3_SECONDS);
97+
await this.page.waitForTimeout(TIMEOUT_10_SECONDS);
9798
await this.bookableToggleContainer.waitFor({ timeout: TIMEOUT_30_SECONDS });
9899
await this.allStartTimeInput.waitFor({ timeout: TIMEOUT_30_SECONDS });
99100
await this.bookingPageMtgDur15MinBtn.waitFor({ timeout: TIMEOUT_30_SECONDS });

test/e2e/pages/settings-page.ts

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
TIMEOUT_1_SECOND,
77
TIMEOUT_2_SECONDS,
88
TIMEOUT_3_SECONDS,
9-
TIMEOUT_10_SECONDS,
9+
TIMEOUT_5_SECONDS,
1010
TIMEOUT_30_SECONDS,
1111
APPT_LANGUAGE_SETTING_EN,
1212
} from '../const/constants';
@@ -86,9 +86,9 @@ export class SettingsPage {
8686
this.connectedAppsBtn = this.page.getByTestId('settings-connectedApplications-settings-btn');
8787
this.connectedAppsHdr = this.page.getByRole('heading', { name: 'Connected Applications' });
8888
this.addCaldavBtn = this.page.getByRole('button', { name: 'Add CalDAV' });
89-
this.addCaldavUsernameInput = this.page.getByRole('textbox', { name: 'user' });
90-
this.addCaldavLocationInput = this.page.getByRole('textbox', { name: 'Location The URL or hostname' });
91-
this.addCaldavPasswordInput = this.page.getByRole('textbox', { name: 'password' });
89+
this.addCaldavUsernameInput = this.page.getByLabel('Username');
90+
this.addCaldavLocationInput = this.page.getByLabel('Location');
91+
this.addCaldavPasswordInput = this.page.getByLabel('Password');
9292
this.addCaldavCloseModalBtn = this.page.getByRole('img', { name: 'Close' });
9393
this.addGoogleBtn = this.page.getByRole('button', { name: 'Add Google Calendar' });
9494
this.defaultCalendarConnectedCbox = this.page.locator('div').filter({ hasText: /^Default*/ }).getByTestId('checkbox-input');
@@ -99,7 +99,7 @@ export class SettingsPage {
9999
*/
100100
async gotoAccountSettings() {
101101
await this.page.goto(APPT_SETTINGS_PAGE);
102-
await this.page.waitForTimeout(TIMEOUT_3_SECONDS);
102+
await this.page.waitForTimeout(TIMEOUT_5_SECONDS);
103103
await this.accountSettingsBtn.scrollIntoViewIfNeeded();
104104
await this.accountSettingsBtn.click();
105105
await this.page.waitForTimeout(TIMEOUT_1_SECOND);
@@ -110,7 +110,7 @@ export class SettingsPage {
110110
*/
111111
async gotoPreferencesSettings() {
112112
await this.page.goto(APPT_SETTINGS_PAGE);
113-
await this.page.waitForTimeout(TIMEOUT_3_SECONDS);
113+
await this.page.waitForTimeout(TIMEOUT_5_SECONDS);
114114
await this.preferencesBtn.scrollIntoViewIfNeeded({ timeout: TIMEOUT_30_SECONDS });
115115
await this.preferencesBtn.click();
116116
await this.page.waitForTimeout(TIMEOUT_1_SECOND);
@@ -121,7 +121,7 @@ export class SettingsPage {
121121
*/
122122
async gotoConnectedAppSettings() {
123123
await this.page.goto(APPT_SETTINGS_PAGE);
124-
await this.page.waitForTimeout(TIMEOUT_3_SECONDS);
124+
await this.page.waitForTimeout(TIMEOUT_5_SECONDS);
125125
await this.connectedAppsBtn.scrollIntoViewIfNeeded();
126126
await this.connectedAppsBtn.click();
127127
await this.page.waitForTimeout(TIMEOUT_1_SECOND);
@@ -161,6 +161,7 @@ export class SettingsPage {
161161
await this.page.waitForTimeout(TIMEOUT_1_SECOND);
162162
await expect(this.savedSuccessfullyTextEN).toBeVisible();
163163
}
164+
await this.page.waitForTimeout(TIMEOUT_5_SECONDS);
164165
}
165166

166167
/**
@@ -174,7 +175,7 @@ export class SettingsPage {
174175
await this.saveBtnEN.click();
175176
await expect(this.savedSuccessfullyTextEN).toBeVisible({ timeout: TIMEOUT_30_SECONDS });
176177
// wait for theme to take affect, can take time especially on browserstack
177-
await this.page.waitForTimeout(TIMEOUT_10_SECONDS);
178+
await this.page.waitForTimeout(TIMEOUT_5_SECONDS);
178179
}
179180

180181
/**
@@ -202,18 +203,6 @@ export class SettingsPage {
202203
await this.saveBtnEN.click();
203204
await this.page.waitForTimeout(TIMEOUT_1_SECOND);
204205
await expect(this.savedSuccessfullyTextEN).toBeVisible();
205-
}
206-
207-
/**
208-
* Change the display name setting
209-
*/
210-
async changeDisplaName(newName: string) {
211-
await this.displayNameInput.scrollIntoViewIfNeeded();
212-
await this.page.waitForTimeout(TIMEOUT_1_SECOND);
213-
await this.displayNameInput.fill(newName);
214-
await this.page.waitForTimeout(TIMEOUT_1_SECOND);
215-
await this.saveBtnEN.scrollIntoViewIfNeeded();
216-
await this.saveBtnEN.click();
217-
await this.page.waitForTimeout(TIMEOUT_3_SECONDS);
206+
await this.page.waitForTimeout(TIMEOUT_5_SECONDS);
218207
}
219208
}

test/e2e/pages/tb-accts-page.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export class TBAcctsPage {
1414

1515
constructor(page: Page) {
1616
this.page = page;
17-
this.signInHeaderText = this.page.getByText('Enter your password');
17+
this.signInHeaderText = this.page.getByText('Sign in to your account');
1818
this.userAvatar = this.page.getByTestId('avatar-default');
1919
this.emailInput = this.page.getByTestId('username-input');
2020
this.passwordInput = this.page.getByTestId('password-input');

test/e2e/playwright.config.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,16 @@ export default defineConfig({
4848

4949
/* Configure projects for major browsers */
5050
projects: [
51-
// Setup project - signs into Appointment once for all the tests
52-
{ name: 'desktop-setup', testMatch: /.*\.desktop.setup\.ts/ },
51+
// Setup browsers - signs into Appointment once for all the tests and saves auth
52+
{ name: 'desktop-setup',
53+
testMatch: /.*\.desktop.setup\.ts/,
54+
use: {
55+
...devices['Desktop Chrome'],
56+
screenshot: 'only-on-failure',
57+
},
58+
},
59+
60+
// Main tests; each browser runs the setup above and saves auth state which is loaded for each test in the suite
5361
{
5462
name: 'chromium',
5563
use: {
@@ -91,6 +99,7 @@ export default defineConfig({
9199
screenshot: 'only-on-failure',
92100
},
93101
},
102+
// no dependency as mobile browsers don't support loading auth state so must sign-in for each test
94103
],
95104

96105
/* Run your local dev server before starting the tests */

0 commit comments

Comments
 (0)