Skip to content

Commit c11fe18

Browse files
committed
feat: add typecheck and lint in CI for tests
1 parent 488fa0b commit c11fe18

File tree

7 files changed

+108
-48
lines changed

7 files changed

+108
-48
lines changed

.github/workflows/playwright.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,24 @@ concurrency:
2424
cancel-in-progress: false
2525

2626
jobs:
27+
typecheck-lint:
28+
name: Typecheck & Lint
29+
runs-on: ubuntu-latest
30+
defaults:
31+
run:
32+
working-directory: packages/e2e-tests
33+
steps:
34+
- uses: actions/checkout@v4
35+
- uses: actions/setup-node@v4
36+
with:
37+
node-version: 20
38+
cache: 'yarn'
39+
- name: Install dependencies
40+
run: yarn install --frozen-lockfile
41+
- name: Run Typecheck
42+
run: yarn typecheck
43+
- name: Run Biome Check
44+
run: yarn biome:ci
2745
test-e2e:
2846
name: E2E Tests
2947
environment: 'test'

packages/e2e-tests/package.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@
1010
},
1111
"scripts": {
1212
"install": "playwright install",
13+
"typecheck": "tsc --noEmit",
1314
"test": "playwright test",
14-
"format": "biome format --write ./tests/*",
15-
"lint": "yarn biome lint --apply ./tests/*",
16-
"biome:check": "biome check --apply ./tests/*"
15+
"format": "biome format ./tests/* ./utils/*",
16+
"lint": "yarn biome lint ./tests/* ./utils/*",
17+
"biome:check": "biome check ./tests/* ./utils/*",
18+
"biome:ci": "biome ci ./tests/* ./utils/*",
19+
"biome:fix": "biome check --write ./tests/* ./utils/*"
1720
},
1821
"dependencies": {
1922
"@togglecorp/fujs": "^2.1.1",

packages/e2e-tests/tests/auth.setup.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,15 @@ import { login } from '#utils/auth';
33
const authFile = 'playwright/.auth/user.json';
44

55
setup('authenticate', async ({ page }) => {
6-
if (process.env.PLAYWRIGHT_USER_NAME && process.env.PLAYWRIGHT_USER_PASSWORD) {
7-
await login(page, process.env.PLAYWRIGHT_USER_NAME, process.env.PLAYWRIGHT_USER_PASSWORD);
6+
if (
7+
process.env.PLAYWRIGHT_USER_NAME &&
8+
process.env.PLAYWRIGHT_USER_PASSWORD
9+
) {
10+
await login(
11+
page,
12+
process.env.PLAYWRIGHT_USER_NAME,
13+
process.env.PLAYWRIGHT_USER_PASSWORD,
14+
);
815
}
916

1017
// End of authentication steps.

packages/e2e-tests/tests/field-report/fieldReport.spec.ts

Lines changed: 49 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import fixtureData from './fieldReport.json';
44

55
test.use({ storageState: 'playwright/.auth/user.json' });
66

7-
test.describe('Field Report', () => {
7+
test.describe('Field Report', () => {
88
test('should create a new event type field report', async ({ page }) => {
99
const {
1010
formName,
@@ -103,19 +103,15 @@ test.describe('Field Report', () => {
103103
await page.getByRole('button', { name: 'Continue' }).click();
104104
// Situation Page
105105
await page.locator('input[name="num_injured"]').fill(numInjured);
106-
await page
107-
.locator('input[name="gov_num_injured"]')
108-
.fill(govNumInjured);
106+
await page.locator('input[name="gov_num_injured"]').fill(govNumInjured);
109107
await page
110108
.locator('input[name="other_num_injured"]')
111109
.fill(otherNumInjured);
112110
await page.locator('input[name="num_dead"]').fill(numDead);
113111
await page.locator('input[name="gov_num_dead"]').fill(govNumDead);
114112
await page.locator('input[name="other_num_dead"]').fill(otherNumDead);
115113
await page.locator('input[name="num_missing"]').fill(numMissing);
116-
await page
117-
.locator('input[name="gov_num_missing"]')
118-
.fill(govNumMissing);
114+
await page.locator('input[name="gov_num_missing"]').fill(govNumMissing);
119115
await page
120116
.locator('input[name="other_num_missing"]')
121117
.fill(otherNumMissing);
@@ -133,9 +129,7 @@ test.describe('Field Report', () => {
133129
await page
134130
.locator('input[name="other_num_displaced"]')
135131
.fill(otherNumDisplaced);
136-
await page
137-
.locator('textarea[name="other_sources"]')
138-
.fill(otherSources);
132+
await page.locator('textarea[name="other_sources"]').fill(otherSources);
139133
// await page.frameLocator('iframe[title="Rich Text Area"]').locator('html').fill("Just the random data");
140134
// issue in Situational overview textbox
141135
await page.getByRole('button', { name: 'Continue' }).click();
@@ -497,28 +491,36 @@ test.describe('Field Report', () => {
497491
await expect(detailLocator).toContainText(detail.email);
498492
await expect(detailLocator).toContainText(detail.phone);
499493
}
500-
await page.getByRole('link', { name: 'Edit Report' }).click();
494+
await page.getByRole('link', { name: 'Edit Report' }).click();
501495
// Input Value Assertions
502496
// Context Page
503497
// Status
504-
const statusValue = page.locator('label').filter({ hasText: 'EventFirst report for this disaster' })
498+
const statusValue = page
499+
.locator('label')
500+
.filter({ hasText: 'EventFirst report for this disaster' });
505501
await expect(statusValue).toBeChecked();
506502
// Assertions for Country, Region, Disaster Type, Date and Title
507503
const countryValue = page.locator('input[name="country"]');
508504
await expect(countryValue).toHaveValue(country);
509-
const regionValue = page.locator('input[name="districts"]')
505+
const regionValue = page.locator('input[name="districts"]');
510506
await expect(regionValue).toHaveValue(district);
511507
const disasterValue = page.locator('input[name="dtype"]');
512508
await expect(disasterValue).toHaveValue(disasterType);
513509
const dateValue = page.locator('input[name="start_date"]');
514510
await expect(dateValue).toHaveValue(date);
515511
const titleValue = page.getByPlaceholder('Example: Cyclone Cody');
516-
await expect(titleValue).toHaveValue(`${newtitle} - ${title}`,);
512+
await expect(titleValue).toHaveValue(`${newtitle} - ${title}`);
517513
// Government request international assistance
518-
const govReqValue = page.locator('label').filter({ hasText: govRequest }).nth(1)
514+
const govReqValue = page
515+
.locator('label')
516+
.filter({ hasText: govRequest })
517+
.nth(1);
519518
await expect(govReqValue).toBeChecked();
520519
// National Society requests international assistance?
521-
const nsReqValue = page.locator('label').filter({ hasText: nationalsocietyRequest }).nth(2)
520+
const nsReqValue = page
521+
.locator('label')
522+
.filter({ hasText: nationalsocietyRequest })
523+
.nth(2);
522524
await expect(nsReqValue).toBeChecked();
523525
await page.getByRole('button', { name: 'Continue' }).click();
524526
// Situation Page
@@ -538,7 +540,7 @@ test.describe('Field Report', () => {
538540
{ name: 'other_num_affected', value: otherNumAffected },
539541
{ name: 'num_displaced', value: numDisplaced },
540542
{ name: 'gov_num_displaced', value: govNumDisplaced },
541-
{ name: 'other_num_displaced', value: otherNumDisplaced }
543+
{ name: 'other_num_displaced', value: otherNumDisplaced },
542544
];
543545
for (const { name, value } of numericDetailValues) {
544546
const inputValue = page.locator(`input[name="${name}"]`);
@@ -555,7 +557,7 @@ test.describe('Field Report', () => {
555557
{ name: 'num_assisted', value: numAssisted },
556558
{ name: 'num_localstaff', value: numLocalstaff },
557559
{ name: 'num_volunteers', value: numVolunteers },
558-
{ name: 'num_expats_delegates', value: numExpatsDelegates }
560+
{ name: 'num_expats_delegates', value: numExpatsDelegates },
559561
];
560562
for (const { name, value } of assistedValues) {
561563
const inputValue = page.locator(`input[name="${name}"]`);
@@ -564,33 +566,51 @@ test.describe('Field Report', () => {
564566
// Assertions for Actions Taken by National Society Red Cross Value
565567
const nsActions = [actionHuman, actionShelter, actionEvacuation];
566568
for (const action of nsActions) {
567-
const label = page.locator('label').filter({ hasText: action }).first();
569+
const label = page
570+
.locator('label')
571+
.filter({ hasText: action })
572+
.first();
568573
await expect(label).toBeChecked();
569574
}
570-
const nsValue = page.getByPlaceholder('Brief description of the action').first();
575+
const nsValue = page
576+
.getByPlaceholder('Brief description of the action')
577+
.first();
571578
await expect(nsValue).toHaveText(nationalSocietySummary);
572579
// Assertions for Actions Taken by IFRC Value
573580
const ifrcActions = [actionHealth, actionShelter, actionCamp];
574581
for (const action of ifrcActions) {
575-
const label = page.locator('label').filter({ hasText: action }).nth(1);
582+
const label = page
583+
.locator('label')
584+
.filter({ hasText: action })
585+
.nth(1);
576586
await expect(label).toBeChecked();
577587
}
578-
const ifrcValue = page.getByPlaceholder('Brief description of the action').nth(1);
588+
const ifrcValue = page
589+
.getByPlaceholder('Brief description of the action')
590+
.nth(1);
579591
await expect(ifrcValue).toHaveText(federationSummary);
580592
// Assertions for Actions Taken by RCRC Movements Value
581593
const rcrcActions = [actionFirst, actionPsychosocial, actionFood];
582594
for (const action of rcrcActions) {
583-
const label = page.locator('label').filter({ hasText: action }).nth(2);
595+
const label = page
596+
.locator('label')
597+
.filter({ hasText: action })
598+
.nth(2);
584599
await expect(label).toBeChecked();
585600
}
586-
const rcrcValue = page.getByPlaceholder('Brief description of the action').nth(2);
601+
const rcrcValue = page
602+
.getByPlaceholder('Brief description of the action')
603+
.nth(2);
587604
await expect(rcrcValue).toHaveText(rcrcSummary);
588605
// Assertions for Information Bulletin
589-
const bulletinValue = page.locator('label').filter({ hasText: informationBulletin });
606+
const bulletinValue = page
607+
.locator('label')
608+
.filter({ hasText: informationBulletin });
590609
await expect(bulletinValue).toBeChecked();
591610
// Assertions for Actions Taken by Others Value
592-
const actionsOtherValue = page.locator('textarea[name="actions_others"]');
593-
await expect(actionsOtherValue).toHaveText(actionOther)
594-
595-
});
611+
const actionsOtherValue = page.locator(
612+
'textarea[name="actions_others"]',
613+
);
614+
await expect(actionsOtherValue).toHaveText(actionOther);
615+
});
596616
});

packages/e2e-tests/tests/loginLogout.spec.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ test('should login', async ({ page }) => {
88
process.env.PLAYWRIGHT_USER_PASSWORD,
99
);
1010
await page.waitForURL('/');
11-
await expect(page.getByRole('button', { name: 'Create a Report' })).toBeVisible();
11+
await expect(
12+
page.getByRole('button', { name: 'Create a Report' }),
13+
).toBeVisible();
1214
});
1315

1416
test('should logout', async ({ page }) => {

packages/e2e-tests/utils/auth.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,7 @@ export async function login(page: Page, username: string, password: string) {
1313
// Wait for the final URL to ensure that the cookies are actually set.
1414
await page.waitForURL('/');
1515
// Alternatively, you can wait until the page reaches a state where all cookies are set.
16-
await expect(page.getByRole('button', { name: 'Create a Report' })).toBeVisible();
16+
await expect(
17+
page.getByRole('button', { name: 'Create a Report' }),
18+
).toBeVisible();
1719
}

packages/e2e-tests/utils/common.ts

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { isNotDefined, isFalsyString, isTruthyString, isDefined } from '@togglecorp/fujs';
1+
import {
2+
isDefined,
3+
isFalsyString,
4+
isNotDefined,
5+
isTruthyString,
6+
} from '@togglecorp/fujs';
27

38
function getMaximumFractionDigits(value: number) {
49
if (value < 1000) {
@@ -25,8 +30,8 @@ interface FormatNumberOptions {
2530
unit?: Intl.NumberFormatOptions['unit'];
2631
maximumFractionDigits?: Intl.NumberFormatOptions['maximumFractionDigits'];
2732
compact?: boolean;
28-
separatorHidden?: boolean,
29-
language?: string,
33+
separatorHidden?: boolean;
34+
language?: string;
3035
}
3136

3237
export function formatNumber(
@@ -35,13 +40,14 @@ export function formatNumber(
3540
) {
3641
const formattingOptions: Intl.NumberFormatOptions = {};
3742

38-
const safeNumber = typeof value === 'string'
39-
? Number(value)
40-
: value;
43+
const safeNumber = typeof value === 'string' ? Number(value) : value;
4144

4245
if (isNotDefined(options)) {
43-
formattingOptions.maximumFractionDigits = getMaximumFractionDigits(safeNumber);
44-
return new Intl.NumberFormat('default', formattingOptions).format(safeNumber);
46+
formattingOptions.maximumFractionDigits =
47+
getMaximumFractionDigits(safeNumber);
48+
return new Intl.NumberFormat('default', formattingOptions).format(
49+
safeNumber,
50+
);
4551
}
4652

4753
const {
@@ -71,11 +77,13 @@ export function formatNumber(
7177
if (isDefined(maximumFractionDigits)) {
7278
formattingOptions.maximumFractionDigits = maximumFractionDigits;
7379
} else {
74-
formattingOptions.maximumFractionDigits = getMaximumFractionDigits(safeNumber);
80+
formattingOptions.maximumFractionDigits =
81+
getMaximumFractionDigits(safeNumber);
7582
}
7683

77-
const newValue = new Intl.NumberFormat(language, formattingOptions)
78-
.format(safeNumber);
84+
const newValue = new Intl.NumberFormat(language, formattingOptions).format(
85+
safeNumber,
86+
);
7987

8088
return newValue;
81-
}
89+
}

0 commit comments

Comments
 (0)