Helper files, application behavior, and configuration#

AI-SAI-Generated Summary H-RHuman Reviewed H-EHuman Edited

The concise specs depend on a toolkit of application workflows, component helpers, configuration, and reporting. This tour locates those responsibilities before the individual helper walkthroughs explain their implementations.

The tree below is a selected view of the suite’s modules and responsibilities, rather than a complete inventory.

The module layout#

src/
├── playwright.config.ts              # Execution, browser, artifacts, reporters
├── url-config.ts                     # Environment-driven application URLs
└── tests/
    ├── admin-portal/                  # Feature specifications by menu/section
    ├── community-portal/
    ├── entity-portal/
    ├── investors-portal/
    ├── transfersolo/
    ├── reporters/
    │   ├── console-reporter.ts        # Reporter selected by active config
    │   ├── failure-debug-reporter.ts
    │   └── notification-reporter.ts
    └── HelperFiles/
        ├── cit-app-helpers.ts         # Login and application workflows
        ├── cit-app-config.ts          # Navigation, options, columns, permissions
        ├── console-reporter.ts        # Earlier/alternate reporter implementation
        ├── components/
        │   ├── buttons.ts            # safeClick and related interactions
        │   ├── dropdowns.ts          # Dropdown selection and checks
        │   ├── common.ts             # Shared table/control operations
        │   ├── verification_checks.ts
        │   ├── settings-helpers.ts   # setupTestPage and settings operations
        │   ├── cit-corp-form.ts       # CIT Corporation workflows
        │   ├── transfersolo-helpers.ts
        │   ├── address/
        │   └── helperFunctions/
        │       ├── addressComponents.ts
        │       └── utilities.ts      # Screenshots and other common utilities
        ├── types/                    # Address and application interfaces
        ├── fixtures/                 # Reusable fixture support
        ├── fixtures.ts
        ├── debug-hooks.ts
        ├── playwright-debug.ts
        ├── playwright-debug-enhanced.ts
        └── deprecated/               # Retained older implementations

The names describe several different responsibilities. A helper performs an operation; a configuration entry supplies a value; a reporter records execution events. Those boundaries explain what the imports in a feature test contribute.

cit-app-helpers.ts: application-level operations#

This module composes lower-level helpers into login and application workflows. It imports configuration, address functions, button interactions, dropdown operations, verification functions, and screenshot utilities.

Inside navigateToSectionAndVerifyFields, navigation, capture, and column checks are composed into one operation:

  console.log('[navigateToSectionAndVerifyFields] Calling clickDropdownFromSideBar');
  await clickDropdownFromSideBar(page, sideNavParent, sideNavChild);

  console.log('[navigateToSectionAndVerifyFields] Calling takeNamedScreenshot (after_navigation)');
  await takeNamedScreenshot(page, 'navigateToSectionAndVerifyFields', 'after_navigation');

  console.log('[navigateToSectionAndVerifyFields] Calling checkColumnHeaders');
  await checkColumnHeaders(
    page, 
    columnHeaderNamesToCheck
  );

The operation combines sidebar navigation, a screenshot, and a configured column check. Test authors can reuse that workflow rather than reproducing the same sequence. This is the application layer of the function-based POM approach; component modules contain more specific browser interactions.

The same module owns role-specific login. Its opening reads the credentials from environment configuration:

export async function loginAsSuperAdmin(page: Page): Promise<void> {
  const user = process.env.CIT_APP_SUPER_ADMIN_LOGIN_NAME;
  const pass = process.env.CIT_APP_SUPER_ADMIN_LOGIN_PASS;

  if (!user || !pass) {
    throw new Error(
      'Must set CIT_APP_SUPER_ADMIN_LOGIN_NAME and CIT_APP_SUPER_ADMIN_LOGIN_PASS in env'
    );
  }

The rest of this function navigates to the configured login URL, fills the existing form, signs in, waits for a post-login URL, and captures a screenshot. The harness calls it during setup. Other roles and applications need their own appropriate login behavior; the presence of a super-admin helper does not make every test role-independent.

cit-app-config.ts: expectations outside the test body#

The configuration file contains named exports for navigation text, dropdown/status options, column labels, permissions, and portal-specific values. It is a TypeScript module with object and array literals.

The columnNames.ProofOfAddress entry supplies list, detail, and history labels to its consumer:

    ProofOfAddress: {
        HomePage: [
            'Investor',
            'Offering',
            'Sponsor Organization',
            'CIT Corporation',
            'Status',
            'Action'
        ],
        DetailFields: [
            'Proof Of Address ID',
            'Status',
            'Sponsor Organization',
            'CIT Corporation',
            'Offering',
            'Address'
        ],
        HistoryTable: [
            'Date',
            'Status',
            'Added By'
        ]
    },
    test('Page loads with correct heading', async () => {
        await verifyHeadingPresence(page, 'Proof of Address', false);
        await checkColumnHeaders(page, columnNames.ProofOfAddress.HomePage);
        await takeNamedScreenshot(page, 'proof_of_address', 'list_page');
        await takeDocScreenshot(page, 'Investors', 'proof-of-address-homepage');
    });

The scenario says which screen to check. The configuration says which labels are expected. The helper says how to find and check them. Changing a genuinely shared label can therefore be handled in one configuration entry, while different portals can retain separate expectations.

The Status test uses the same arrangement: statusOptions.ProofOfAddress supplies All, Pending Approval, Need More Info, Denied, and Approved.

Keep four kinds of configuration distinct:

Location

What it configures

Playwright runner configuration

How tests run, browser projects, retries, artifact capture, and reporters.

URL configuration and environment variables

Application destinations and environment/role-specific settings.

Application configuration

Expected UI values and application navigation used by test code.

Machine-readable helper references

Function definitions and conversion guidance for agents.

I used TypeScript exports in cit-app-config.ts for test expectations, JSON helper references for agents, and separate JSON column descriptions for documentation. The evolution page covers the helper references and reuse across portals; the manual-draft page explains the column descriptions.

console-reporter.ts: making execution inspectable#

The console-reporter.ts module provides a concrete reporter example. It implements the reporter interface, creates test-output logs, manages streams by test ID, records start/end events and status, and restores overridden console methods at the end.

  onTestBegin(test: TestCase) {
    // Create a new file for this test
    const outputFile = this.createOutputFileForTest(test);
    this.activeTestId = test.id;
    outputFile.write(`[${new Date().toISOString()}] Test started: ${test.title}\n`);
    
    // Also log to the run log
    const runLog = this.getOutputFile('run');
    if (runLog) {
      runLog.write(`[${new Date().toISOString()}] Test started: ${test.title}\n`);
    }
  }

  onTestEnd(test: TestCase, result: TestResult) {
    const outputFile = this.getOutputFile(test.id);
    if (outputFile) {
      outputFile.write(`[${new Date().toISOString()}] Test ended: ${test.title} (${result.status})\n`);
      outputFile.end();
      this.outputFiles.delete(test.id);
    }

The test title becomes readable context in the log; test.id associates it with an output stream; result.status records the runner’s outcome. The corresponding illustrative output format is:

[timestamp] Test started: Page loads with correct heading
[timestamp] Test ended: Page loads with correct heading (passed)

The full reporter also writes a run log and error messages. Its console override describes a logging strategy, while its single active-test field is not suited to general parallel-log routing.

The active Playwright configuration selects a different console-reporter implementation from the helper example shown above. That selection determines which implementation a current run uses. The runner also enables failure-debug and notification reporters, plus JSON, HTML, and JUnit output.

The same runner sets one worker, disables full parallelism, uses two retries in CI and none locally, and retains failure artifacts. Those settings do not by themselves establish that the suite is free of timing failures.

Continue into the detailed implementations: email templates, primary/mailing addresses, named screenshots, and selector diagnostics. These pages show complete functions and larger examples with setup and configuration.

Bring the parts together#

Together, the modules supply the following parts of a test:

Spec: named workflow steps
  + App config: expected values
  + Harness: session and starting page
  + Domain/component helpers: behavior
  + Utilities: screenshots and shared operations
  + Runner/reporters: execution and evidence
  = A test that another developer or agent can inspect and extend

The docs-as-code chapter follows the next maintenance need: once the toolkit became substantial, developers needed explanations, generated function references, and guidance for deprecated helpers. Later, that same documented toolkit became context for agents generating and repairing tests.