Skip to content

Commit ee4972c

Browse files
Address review comments and made updates post discussion
1 parent 35faa3c commit ee4972c

14 files changed

+353
-408
lines changed

.github/actions/e2e/action.yml

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ inputs:
1717
description: "mfa key for staging test user"
1818
playwright_tags:
1919
description: "pipe separated list of tags denoting groups of tests to run"
20-
playwright_tags_invert:
21-
description: "pipe separated list of tags to exclude from test run"
2220
total_shards:
2321
description: "total number of test shards in parent run"
2422
default: "1"
@@ -43,9 +41,9 @@ inputs:
4341
node_options:
4442
description: "options to pass to node"
4543
default: "--dns-result-order=ipv4first"
46-
report_name_prefix:
47-
description: "prefix for blob report artifact name"
48-
default: "blob-report"
44+
workers:
45+
description: "number of workers to use for test run"
46+
default: ""
4947
outputs:
5048
artifact-id:
5149
description: "artifact ids for uploaded test reports"
@@ -85,13 +83,14 @@ runs:
8583
npx playwright install --with-deps
8684
8785
- name: Run all e2e tests (Shard ${{ inputs.current_shard }}/${{ inputs.total_shards }})
88-
if: ${{ inputs.playwright_tags == '' && inputs.playwright_tags_invert == '' }}
86+
if: ${{ inputs.playwright_tags == '' }}
8987
working-directory: ./frontend
9088
env:
9189
CI: true
9290
TOTAL_SHARDS: ${{ inputs.total_shards }}
9391
CURRENT_SHARD: ${{ inputs.current_shard }}
9492
PLAYWRIGHT_TARGET_ENV: ${{ inputs.target }}
93+
PLAYWRIGHT_WORKERS: ${{ inputs.workers }}
9594
STAGING_TEST_USER_EMAIL: ${{ inputs.staging_test_user_email }}
9695
STAGING_TEST_USER_PASSWORD: ${{ inputs.staging_test_user_password }}
9796
STAGING_TEST_USER_MFA_KEY: ${{ inputs.staging_test_user_mfa_key }}
@@ -107,28 +106,14 @@ runs:
107106
TOTAL_SHARDS: ${{ inputs.total_shards }}
108107
CURRENT_SHARD: ${{ inputs.current_shard }}
109108
PLAYWRIGHT_TARGET_ENV: ${{ inputs.target }}
109+
PLAYWRIGHT_WORKERS: ${{ inputs.workers }}
110110
STAGING_TEST_USER_EMAIL: ${{ inputs.staging_test_user_email }}
111111
STAGING_TEST_USER_PASSWORD: ${{ inputs.staging_test_user_password }}
112112
STAGING_TEST_USER_MFA_KEY: ${{ inputs.staging_test_user_mfa_key }}
113113
run: |
114114
npm run test:e2e -- --grep "${{ inputs.playwright_tags }}"
115115
shell: bash
116116

117-
- name: Run e2e tests excluding ${{ inputs.playwright_tags_invert }} (Shard ${{ inputs.current_shard }}/${{ inputs.total_shards }})
118-
if: ${{ inputs.playwright_tags_invert != '' }}
119-
working-directory: ./frontend
120-
env:
121-
CI: true
122-
TOTAL_SHARDS: ${{ inputs.total_shards }}
123-
CURRENT_SHARD: ${{ inputs.current_shard }}
124-
PLAYWRIGHT_TARGET_ENV: ${{ inputs.target }}
125-
STAGING_TEST_USER_EMAIL: ${{ inputs.staging_test_user_email }}
126-
STAGING_TEST_USER_PASSWORD: ${{ inputs.staging_test_user_password }}
127-
STAGING_TEST_USER_MFA_KEY: ${{ inputs.staging_test_user_mfa_key }}
128-
run: |
129-
npm run test:e2e -- --grep-invert "${{ inputs.playwright_tags_invert }}"
130-
shell: bash
131-
132117
- name: Debug logging on failure
133118
if: ${{ failure() && inputs.api_logs == 'true' }}
134119
working-directory: ./frontend
@@ -160,6 +145,6 @@ runs:
160145
if: always()
161146
uses: actions/upload-artifact@v6
162147
with:
163-
name: ${{ inputs.report_name_prefix }}-shard-${{ inputs.current_shard }}
148+
name: blob-report-shard-${{ inputs.current_shard }}
164149
path: /home/runner/work/simpler-grants-gov/simpler-grants-gov/frontend/blob-report
165150
retention-days: 1

.github/workflows/e2e-create-report.yml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,7 @@ jobs:
3939
path: frontend/all-blob-reports
4040
# artifact-ids: ${{ inputs.artifact-ids }}
4141
run-id: ${{ inputs.run_id }}
42-
# Matches report_name_prefix values set by callers:
43-
# - blob-report-no-auth (e2e-staging.yml sharded job)
44-
# - blob-report-auth (e2e-staging.yml auth job)
45-
# - blob-report (ci-frontend-e2e.yml default)
46-
pattern: blob-report*-shard-*
42+
pattern: blob-report-shard-*
4743
merge-multiple: true
4844
- name: Verify Downloaded Artifacts
4945
run: |

.github/workflows/e2e-staging.yml

Lines changed: 4 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -24,34 +24,7 @@ concurrency:
2424
group: ${{ github.workflow }}-${{ github.ref }}
2525
cancel-in-progress: true
2626
jobs:
27-
e2e-tests-no-auth-sharded:
28-
name: Run Non-Auth E2E Tests
29-
runs-on: ubuntu-22.04
30-
strategy:
31-
fail-fast: false
32-
matrix:
33-
shard: [1, 2, 3, 4]
34-
total_shards: [4]
35-
steps:
36-
- name: Checkout repository
37-
uses: actions/checkout@v6
38-
- name: Set target
39-
run: if [[ -z "${{ inputs.target }}" ]]; then echo "defaulted_target=staging" >> "$GITHUB_ENV"; else echo "defaulted_target=${{ inputs.target }}" >> "$GITHUB_ENV"; fi
40-
- name: Run E2E tests
41-
uses: ./.github/actions/e2e
42-
with:
43-
version: ${{ inputs.version || github.ref }}
44-
target: ${{ env.defaulted_target }}
45-
total_shards: ${{ matrix.total_shards }}
46-
current_shard: ${{ matrix.shard }}
47-
playwright_tags_invert: "@auth"
48-
staging_test_user_email: ${{ secrets.STAGING_TEST_USER_EMAIL }}
49-
staging_test_user_password: ${{ secrets.STAGING_TEST_USER_PASSWORD }}
50-
staging_test_user_mfa_key: ${{ secrets.STAGING_TEST_USER_MFA_KEY }}
51-
report_name_prefix: blob-report-no-auth
52-
53-
e2e-tests-auth-single-worker:
54-
name: Run Auth E2E Tests
27+
e2e-tests-deployed:
5528
runs-on: ubuntu-22.04
5629
steps:
5730
- name: Checkout repository
@@ -65,21 +38,19 @@ jobs:
6538
target: ${{ env.defaulted_target }}
6639
total_shards: 1
6740
current_shard: 1
68-
playwright_tags: "@auth"
41+
workers: 1
42+
playwright_tags: ${{ inputs.playwright_tags }}
6943
staging_test_user_email: ${{ secrets.STAGING_TEST_USER_EMAIL }}
7044
staging_test_user_password: ${{ secrets.STAGING_TEST_USER_PASSWORD }}
7145
staging_test_user_mfa_key: ${{ secrets.STAGING_TEST_USER_MFA_KEY }}
72-
report_name_prefix: blob-report-auth
73-
7446
create-report:
7547
name: Create Merged Test Report
7648
if: ${{ !cancelled() }}
77-
needs: [e2e-tests-no-auth-sharded, e2e-tests-auth-single-worker]
49+
needs: e2e-tests-deployed
7850
uses: ./.github/workflows/e2e-create-report.yml
7951
secrets: inherit
8052
with:
8153
run_id: ${{ github.run_id }}
82-
8354
send-slack-notification:
8455
if: failure()
8556
needs: [create-report]

frontend/tests/e2e/apply/failure-path-sf424b.spec.ts

Lines changed: 30 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -24,37 +24,33 @@ const sf424bErrors = [
2424
},
2525
];
2626

27-
test(
28-
"SF-424B error validation - required fields and inline errors",
29-
{ tag: "@auth" },
30-
async (
31-
{ page, context }: { page: Page; context: BrowserContext },
32-
testInfo: TestInfo,
33-
) => {
34-
test.setTimeout(300_000); // 5 min timeout
35-
36-
const isMobile = testInfo.project.name.match(/[Mm]obile/);
37-
38-
await authenticateE2eUser(page, context, !!isMobile);
39-
40-
await createApplication(page, OPPORTUNITY_URL, testOrgLabel);
41-
const applicationUrl = page.url();
42-
43-
if (await openForm(page, SF424B_FORM_MATCHER)) {
44-
// Do not enter anything and click save
45-
await saveForm(page, true); // expect validation errors
46-
47-
// Checks error alert list at top of form page
48-
// Scrolls down and checks inline field errors on form page
49-
// Navigates to application landing page
50-
// Scrolls down and checks "Some issues found" in form row
51-
await verifyFormStatusAfterSave(
52-
page,
53-
"incomplete",
54-
"SF-424B",
55-
applicationUrl,
56-
sf424bErrors,
57-
);
58-
}
59-
},
60-
);
27+
test("SF-424B error validation - required fields and inline errors", async ({
28+
page,
29+
context,
30+
}: { page: Page; context: BrowserContext }, testInfo: TestInfo) => {
31+
test.setTimeout(300_000); // 5 min timeout
32+
33+
const isMobile = testInfo.project.name.match(/[Mm]obile/);
34+
35+
await authenticateE2eUser(page, context, !!isMobile);
36+
37+
await createApplication(page, OPPORTUNITY_URL, testOrgLabel);
38+
const applicationUrl = page.url();
39+
40+
if (await openForm(page, SF424B_FORM_MATCHER)) {
41+
// Do not enter anything and click save
42+
await saveForm(page, true); // expect validation errors
43+
44+
// Checks error alert list at top of form page
45+
// Scrolls down and checks inline field errors on form page
46+
// Navigates to application landing page
47+
// Scrolls down and checks "Some issues found" in form row
48+
await verifyFormStatusAfterSave(
49+
page,
50+
"incomplete",
51+
"SF-424B",
52+
applicationUrl,
53+
sf424bErrors,
54+
);
55+
}
56+
});

frontend/tests/e2e/apply/fill-sflll-form.spec.ts

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { fillForm } from "tests/e2e/utils/forms/general-forms-filling";
1111
import {
1212
clearPageState,
1313
ensurePageClosed,
14-
} from "tests/e2e/utils/lifecycle-helpers";
14+
} from "tests/e2e/utils/lifecycle-utils";
1515

1616
const { baseUrl, testOrgLabel, opportunityId } = playwrightEnv;
1717
const OPPORTUNITY_URL = `/opportunity/${opportunityId}`;
@@ -24,36 +24,30 @@ test.describe("fill SF-LLL Form", () => {
2424

2525
test.setTimeout(120000);
2626

27-
test(
28-
"should fill SFLLL form",
29-
{ tag: "@auth" },
30-
async ({ page, context }, testInfo) => {
31-
try {
32-
await page.goto(`${baseUrl}${OPPORTUNITY_URL}`, {
33-
waitUntil: "load",
34-
timeout: 30000,
35-
});
36-
37-
await createApplication(page, OPPORTUNITY_URL, testOrgLabel);
38-
39-
const sflllData = FORMS_TEST_DATA.sflll;
40-
41-
await fillForm(testInfo, page, {
42-
formName: SFLLL_FORM_CONFIG.formName,
43-
fields: getSflllFillFields(sflllData),
44-
saveButtonTestId: SFLLL_FORM_CONFIG.saveButtonTestId,
45-
returnToApplication: false,
46-
});
47-
48-
await expect(
49-
page.getByText(SFLLL_FORM_CONFIG.noErrorsText),
50-
).toBeVisible({
51-
timeout: 15000,
52-
});
53-
} finally {
54-
await clearPageState(context);
55-
await ensurePageClosed(page);
56-
}
57-
},
58-
);
27+
test("should fill SFLLL form", async ({ page, context }, testInfo) => {
28+
try {
29+
await page.goto(`${baseUrl}${OPPORTUNITY_URL}`, {
30+
waitUntil: "load",
31+
timeout: 30000,
32+
});
33+
34+
await createApplication(page, OPPORTUNITY_URL, testOrgLabel);
35+
36+
const sflllData = FORMS_TEST_DATA.sflll;
37+
38+
await fillForm(testInfo, page, {
39+
formName: SFLLL_FORM_CONFIG.formName,
40+
fields: getSflllFillFields(sflllData),
41+
saveButtonTestId: SFLLL_FORM_CONFIG.saveButtonTestId,
42+
returnToApplication: false,
43+
});
44+
45+
await expect(page.getByText(SFLLL_FORM_CONFIG.noErrorsText)).toBeVisible({
46+
timeout: 15000,
47+
});
48+
} finally {
49+
await clearPageState(context);
50+
await ensurePageClosed(page);
51+
}
52+
});
5953
});

frontend/tests/e2e/apply/happy-path-application-submission.spec.ts

Lines changed: 33 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -22,55 +22,46 @@ const OPPORTUNITY_ID = "f7a1c2b3-4d5e-6789-8abc-1234567890ab"; // TEST-APPLY-ORG
2222
const OPPORTUNITY_URL = `/opportunity/${OPPORTUNITY_ID}`;
2323

2424
// Added @auth tag to login-dependent tests so workflows can select them automatically.
25-
test(
26-
"Application submission happy path - application with required SF424B and unsubmitted conditional SFLLL",
27-
{ tag: "@auth" },
28-
async (
29-
{ page, context }: { page: Page; context: BrowserContext },
30-
testInfo: TestInfo,
31-
) => {
32-
test.setTimeout(300_000); // 5 min timeout
25+
test("Application submission happy path - application with required SF424B and unsubmitted conditional SFLLL", async ({
26+
page,
27+
context,
28+
}: { page: Page; context: BrowserContext }, testInfo: TestInfo) => {
29+
test.setTimeout(300_000); // 5 min timeout
3330

34-
const isMobile = testInfo.project.name.match(/[Mm]obile/);
31+
const isMobile = testInfo.project.name.match(/[Mm]obile/);
3532

36-
await authenticateE2eUser(page, context, !!isMobile);
33+
await authenticateE2eUser(page, context, !!isMobile);
3734

38-
// Call reusable create application function from utils
39-
await createApplication(page, OPPORTUNITY_URL, testOrgLabel);
40-
const applicationUrl = page.url();
35+
// Call reusable create application function from utils
36+
await createApplication(page, OPPORTUNITY_URL, testOrgLabel);
37+
const applicationUrl = page.url();
4138

42-
if (!(await openForm(page, SF424B_FORM_MATCHER))) {
43-
throw new Error(
44-
"Could not find or open SF-424B form link on the application forms page",
45-
);
46-
}
39+
if (!(await openForm(page, SF424B_FORM_MATCHER))) {
40+
throw new Error(
41+
"Could not find or open SF-424B form link on the application forms page",
42+
);
43+
}
4744

48-
// Fill SF-424B form fields using helper
49-
await fillSf424bForm(page, "TESTER", testOrgLabel);
45+
// Fill SF-424B form fields using helper
46+
await fillSf424bForm(page, "TESTER", testOrgLabel);
5047

51-
// Save the form using helper
52-
await saveForm(page);
48+
// Save the form using helper
49+
await saveForm(page);
5350

54-
// Verify form status after save
55-
await verifyFormStatusAfterSave(
56-
page,
57-
"complete",
58-
"SF-424B",
59-
applicationUrl,
60-
);
51+
// Verify form status after save
52+
await verifyFormStatusAfterSave(page, "complete", "SF-424B", applicationUrl);
6153

62-
// Extra wait for page to fully render forms table after navigation
63-
await page.waitForTimeout(10000);
54+
// Extra wait for page to fully render forms table after navigation
55+
await page.waitForTimeout(10000);
6456

65-
// Select 'No' for including SF-LLL form in submission
66-
await selectFormInclusionOption(
67-
page,
68-
"Disclosure of Lobbying Activities (SF-LLL)",
69-
"No",
70-
);
57+
// Select 'No' for including SF-LLL form in submission
58+
await selectFormInclusionOption(
59+
page,
60+
"Disclosure of Lobbying Activities (SF-LLL)",
61+
"No",
62+
);
7163

72-
// Submit the application and verify success
73-
await submitApplicationAndVerify(page);
74-
// Application ID is now available in appId variable for further use if needed
75-
},
76-
);
64+
// Submit the application and verify success
65+
await submitApplicationAndVerify(page);
66+
// Application ID is now available in appId variable for further use if needed
67+
});

0 commit comments

Comments
 (0)