Skip to content

Convert e2e-pw CJS utils and barrel index to TypeScript#63318

Merged
adimoldovan merged 17 commits intotrunkfrom
e2e-pw-ts-conversion-09
Feb 19, 2026
Merged

Convert e2e-pw CJS utils and barrel index to TypeScript#63318
adimoldovan merged 17 commits intotrunkfrom
e2e-pw-ts-conversion-09

Conversation

@lucatume
Copy link
Copy Markdown
Contributor

Submission Review Guidelines:

Changes proposed in this Pull Request:

This is the ninth PR in the series to convert the WooCommerce e2e-pw tests from JavaScript to TypeScript, building on the scaffolding introduced in #63188.

Changes:

  • Convert 12 CJS utils to TypeScript in utils/:
    • cli.ts, coming-soon.ts, editor.ts, features.ts, helpers.ts, login.ts, payments-settings.ts, product-block-editor.ts, simple-products.ts, tours.ts, variable-products.ts, wordpress.ts
  • Convert barrel index.js to index.ts — CJS require → ESM import * as, module.exportsexport
  • Full CJS→ESM conversion for all 13 files (requireimport, module.exportsexport)
  • Minimal type annotations added where TypeScript cannot infer types (function parameters only)
  • Named interfaces ProductAttribute and Variation extracted from JSDoc types in variable-products.ts for reuse across multiple functions
  • Dependency group comments added to all files per @woocommerce/dependency-group ESLint rule
  • All JSDoc comments preserved from originals

Conversion approach:

Each file was renamed from .js to .ts via git mv in a dedicated rename commit, then content changes (type annotations, CJS→ESM) were applied in a separate commit. This preserves git log --follow history and git blame attribution.

PR series plan:

  1. Add TypeScript support scaffolding for e2e-pw tests #63188 — TypeScript scaffolding (tsconfig.json, ESLint config)
  2. Convert e2e-pw test specs to TypeScript (batch 1) #63190 — Convert first batch of test specs (basic, brands, customer, editor, js-file-monitor, marketing)
  3. Convert e2e-pw test specs to TypeScript (batch 2) #63198 — Convert second batch of test specs (cart, checkout, coupons, order, shipping, shop)
  4. Convert e2e-pw test specs to TypeScript (batch 3) #63212 — Convert third batch of test specs (merchant, payment, product/classic-editor, tax)
  5. Convert e2e-pw test specs to TypeScript (batch 4) #63213 — Convert fourth batch of test specs (product/block-editor, onboarding, my-account)
  6. Convert e2e-pw test specs to TypeScript (batch 5) #63214 — Convert fifth batch of test specs (email, email-editor, settings, user, wp-core)
  7. Convert e2e-pw API tests to TypeScript #63314 — Convert API tests to TypeScript (CJS→ESM)
  8. Convert e2e-pw fixtures and ESM utils to TypeScript #63315 — Convert fixtures and ESM utils to TypeScript
  9. This PR — Convert CJS utils and barrel index to TypeScript
  10. Subsequent PRs — Convert reporters, test data, and data files
  11. Final PR — Convert Playwright configuration files

How to test the changes in this Pull Request:

Follow the instructions in the plugins/woocommerce/tests/e2e-pw/README.md file.

Testing that has already taken place:

  • Verified all 13 converted .ts files pass ESLint with zero errors (warnings only for import/no-extraneous-dependencies package resolution).
  • Confirmed all files are tracked as git renames.
  • Verified no behavioral changes — purely mechanical conversion with minimal type annotations.

Milestone

Changelog entry

  • Automatically create a changelog entry from the details below.
  • This Pull Request does not require a changelog entry. (Comment required below)

Changelog entry was created manually in this PR.

Changelog Entry Details

Significance

  • Patch

Type

  • Dev - Development related task

Message

Convert e2e-pw CJS utils and barrel index to TypeScript.

Rename 13 utility files to TypeScript extension to preserve git history
before converting the content.
@lucatume lucatume self-assigned this Feb 16, 2026
@github-actions github-actions Bot added focus: e2e tests Issues related to e2e tests plugin: woocommerce Issues related to the WooCommerce Core plugin. labels Feb 16, 2026
@lucatume lucatume marked this pull request as ready for review February 16, 2026 10:48
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 16, 2026

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

E2E test utilities under plugins/woocommerce/tests/e2e-pw/utils/ were converted from CommonJS JavaScript to TypeScript ES modules: JS files removed, .ts equivalents added, functions received type annotations, exports switched to named ES exports, and a new index.ts re-exports utilities. (47 words)

Changes

Cohort / File(s) Summary
CLI
plugins/woocommerce/tests/e2e-pw/utils/cli.js, plugins/woocommerce/tests/e2e-pw/utils/cli.ts
Removed CommonJS cli.js; added cli.ts exporting wpCLI(command: string): Promise<{ stdout: string; stderr: string }> which promisifies child_process.exec and runs pnpm exec wp-env run tests-cli -- <command>.
Coming Soon & Payments Settings
plugins/woocommerce/tests/e2e-pw/utils/coming-soon.js, .../coming-soon.ts, plugins/woocommerce/tests/e2e-pw/utils/payments-settings.js, .../payments-settings.ts
Replaced JS modules with TypeScript equivalents exporting setComingSoon({ baseURL, enabled }) and resetGatewayOrder(baseURL); preserved logic, added typings and named exports.
Editor, Helpers & Index aggregation
plugins/woocommerce/tests/e2e-pw/utils/editor.ts, plugins/woocommerce/tests/e2e-pw/utils/helpers.ts, plugins/woocommerce/tests/e2e-pw/utils/index.js, .../index.ts
Converted to ES modules with TypeScript types; replaced require with import, switched to named exports (fillPageTitle, random), removed old index.js, added index.ts that re-exports utilities.
Features & WordPress utils
plugins/woocommerce/tests/e2e-pw/utils/features.ts, plugins/woocommerce/tests/e2e-pw/utils/wordpress.ts
Migrated to TS ESM, added type annotations for request/core/github interfaces, updated signatures (e.g., setFeatureFlag), and added new WordPress helpers (getVersionWPLatestMinusOne, getInstalledWordPressVersion).
Login & Tours
plugins/woocommerce/tests/e2e-pw/utils/login.ts, plugins/woocommerce/tests/e2e-pw/utils/tours.ts
Converted to TypeScript ES modules, added Page/APIRequestContext typings, and switched to named exports (logIn, logInFromMyAccount, toggleBlockProductTour, toggleVariableProductTour).
Product helpers & Simple products
plugins/woocommerce/tests/e2e-pw/utils/product-block-editor.ts, plugins/woocommerce/tests/e2e-pw/utils/simple-products.ts, plugins/woocommerce/tests/e2e-pw/utils/variable-products.ts
Rewrote as TypeScript ES modules: added explicit types (Page, Browser, ProductAttribute, Variation), updated function signatures (e.g., createVariableProduct, updateProduct), and switched to named exports.
Changelog
plugins/woocommerce/changelog/e2e-pw-ts-conversion-09
Added changelog entry documenting e2e-pw utilities conversion to TypeScript (dev/patch metadata).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the primary change: converting 13 CJS utility files to TypeScript and converting the barrel index.js to index.ts with full ESM conversion.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, providing detailed context about the conversion, testing performed, and the broader PR series.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch e2e-pw-ts-conversion-09

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
plugins/woocommerce/tests/e2e-pw/utils/wordpress.ts (2)

31-33: ⚠️ Potential issue | 🟡 Minor

Potential null dereference in chained .find().match()[0].

If no version in the API response has 'latest' status, .find() returns undefined and .match() throws. Similarly, if the version string doesn't match the regex, .match() returns null and [0] throws.

This is pre-existing logic, but since you're converting to TypeScript, the compiler may flag this depending on strictNullChecks. Worth adding a guard.

🛡️ Suggested defensive approach
-	const latestMajorAndMinorNumbers = allVersions
-		.find( ( version ) => body[ version ] === 'latest' )
-		.match( /^\d+.\d+/ )[ 0 ];
+	const latestVersion = allVersions.find(
+		( version ) => body[ version ] === 'latest'
+	);
+	if ( ! latestVersion ) {
+		throw new Error( 'No latest WordPress version found in API response' );
+	}
+	const match = latestVersion.match( /^\d+\.\d+/ );
+	if ( ! match ) {
+		throw new Error( `Unexpected version format: ${ latestVersion }` );
+	}
+	const latestMajorAndMinorNumbers = match[ 0 ];

Note: the regex /^\d+.\d+/ also uses an unescaped . which matches any character, not just a literal dot. Should be \. — though in practice this won't cause incorrect matches for version strings.


49-53: ⚠️ Potential issue | 🟡 Minor

error in catch is typed unknown under strict TypeScript.

With strict: true in the tsconfig, useUnknownInCatchVariables defaults to enabled (TypeScript 4.4+). Accessing error.message directly will fail to compile because error is typed as unknown.

Suggested fix
 	} catch ( error ) {
 		throw new Error(
-			`Error getting WordPress version: ${ error.message }`
+			`Error getting WordPress version: ${ error instanceof Error ? error.message : error }`
 		);
 	}
🤖 Fix all issues with AI agents
In `@plugins/woocommerce/tests/e2e-pw/utils/features.ts`:
- Around line 7-11: The request parameter in setFeatureFlag and
resetFeatureFlags is currently untyped; update both function signatures to type
request as APIRequestContext (importing APIRequestContext from `@playwright/test`
if not already imported) so they match sibling files like tours.ts and maintain
consistent type annotations across the converted tests.

In `@plugins/woocommerce/tests/e2e-pw/utils/variable-products.ts`:
- Around line 11-21: ProductAttribute and Variation are not exported, so
consumers importing the module (e.g., import * as variableProducts) cannot
access them; add the export keyword to the declarations for ProductAttribute and
Variation so they become public types available to other modules (update the
interface declarations named ProductAttribute and Variation to be exported).
🧹 Nitpick comments (4)
plugins/woocommerce/tests/e2e-pw/utils/payments-settings.ts (1)

14-15: Use console.error for error output.

Errors should go to stderr via console.error rather than console.log so they're distinguishable in CI logs.

Suggested fix
 	} catch ( error ) {
-		console.log( error );
+		console.error( error );
 	}
plugins/woocommerce/tests/e2e-pw/utils/coming-soon.ts (1)

18-22: Consider re-throwing after logging to surface setup failures.

The catch block swallows the error, so callers have no signal that the "coming soon" option wasn't set. A silently failed precondition can cause misleading downstream test failures that are hard to diagnose.

♻️ Suggested improvement
 	try {
 		await setOption( request, baseURL, 'woocommerce_coming_soon', enabled );
 	} catch ( error ) {
 		console.log( error );
+		throw error;
 	}
plugins/woocommerce/tests/e2e-pw/utils/variable-products.ts (1)

190-196: combine inner function parameters have implicit any types.

runningList and nextAttribute are untyped function parameters, which will be implicitly any under strict TypeScript. This is pre-existing complexity from the JS version, but since the PR adds type annotations to all other function parameters, these stand out. Consider typing them in a follow-up if noImplicitAny is enabled or planned.

plugins/woocommerce/tests/e2e-pw/utils/cli.ts (1)

9-15: Shell command injection risk via unsanitized command parameter.

exec spawns a shell, and command is interpolated directly into the string. Any shell metacharacters in command (;, |, $(), etc.) would be interpreted. While callers are internal test code today, the coding guidelines require guarding against unexpected inputs.

A safer alternative would be execFile (no shell) or at minimum a basic validation/allowlist on the command string. Since this is test-only utility code, this is low-priority but worth being aware of.

Comment thread plugins/woocommerce/tests/e2e-pw/utils/features.ts
Comment thread plugins/woocommerce/tests/e2e-pw/utils/variable-products.ts Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
plugins/woocommerce/tests/e2e-pw/utils/variable-products.ts (2)

26-26: Module-level mutable productIds — acceptable for test utilities but worth a note.

The shared mutable array accumulates IDs across calls, and deleteProductsAddedByTests clears them via the API but never resets the array itself. If tests call deleteProductsAddedByTests and then create more products, the array will still contain the old (now-deleted) IDs alongside the new ones, causing a redundant (or failing) delete on the next cleanup call. This is likely fine in practice given test isolation, just calling it out.

Also applies to: 119-131, 137-139

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/woocommerce/tests/e2e-pw/utils/variable-products.ts` at line 26, The
module-level mutable array productIds retains deleted IDs causing
redundant/failing cleanup; update the cleanup routine deleteProductsAddedByTests
(and any other functions that clear via API) to also reset the in-memory array
(e.g., productIds.length = 0 or assign a new empty array) after successful
deletion, and ensure any functions that push to productIds (the helpers that
create test products) continue to push fresh IDs; this guarantees productIds
doesn't accumulate stale IDs across test runs.

189-228: The combine helper has an inconsistent return shape when attributes has only one element.

When attributes.length === 1, generateVariationsFromAttributes returns string[] (the raw options), but with 2+ attributes it returns string[][]. The declared type of allVariations (string[] | string[][]) accurately reflects this, but callers must handle both shapes — which is error-prone.

This is pre-existing behavior from the JS version, so not blocking, but worth noting for a future cleanup: you could normalize the single-attribute case to return string[][] (e.g., attributes[0].options.map(o => [o])) so the return type is always string[][].

Also, attributes[0].options on line 220 will throw if called with an empty array. A guard would make this safer, though admittedly this is a test utility with controlled inputs.

♻️ Optional: normalize the initial value so the return type is always `string[][]`
-	let allVariations: string[] | string[][] = attributes[ 0 ].options;
+	if ( attributes.length === 0 ) {
+		return [];
+	}
+
+	let allVariations: string[][] = attributes[ 0 ].options.map( ( o ) => [ o ] );
 
 	for ( let i = 1; i < attributes.length; i++ ) {
 		const nextAttribute = attributes[ i ].options;
 
 		allVariations = combine( allVariations, nextAttribute );
 	}

This would also let you simplify combine to always accept string[][], removing the union type and the normalization branch.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/woocommerce/tests/e2e-pw/utils/variable-products.ts` around lines 189
- 228, generateVariationsFromAttributes returns inconsistent shapes: when
attributes.length === 1 it returns string[] (raw options) but for 2+ attributes
it returns string[][]; also attributes[0].options will throw if attributes is
empty. Fix by normalizing the initial value and combine signature: convert the
single-attribute case into an array-of-arrays (e.g. map options to [o]) so
allVariations is always string[][], simplify combine to accept string[][] and
always return string[][], and add a guard at the start of
generateVariationsFromAttributes to handle or early-return when attributes is
empty.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@plugins/woocommerce/tests/e2e-pw/utils/wordpress.ts`:
- Around line 43-47: latestMinus1 (result of previousStableVersions.find) can be
undefined and is passed to core.setOutput('version', latestMinus1); update the
logic around previousStableVersions and latestMinus1 to handle the undefined
case: after computing latestMinus1 validate it (e.g., if (!latestMinus1) throw
an Error or set a sensible fallback string) before calling core.setOutput;
reference the variables latestMinus1, previousStableVersions and the call to
core.setOutput to locate and change the behavior so a missing version does not
pass undefined downstream.
- Line 57: The catch clause in the try/catch uses a concrete type (catch (error:
Error)) which TypeScript disallows; change it to use catch (error: unknown) (or
catch (error: any)) in plugins/woocommerce/tests/e2e-pw/utils/wordpress.ts, and
if you need Error properties later, narrow it inside the catch (e.g., via
instanceof Error) before accessing message/stack so the code compiles and
remains type-safe.

---

Nitpick comments:
In `@plugins/woocommerce/tests/e2e-pw/utils/variable-products.ts`:
- Line 26: The module-level mutable array productIds retains deleted IDs causing
redundant/failing cleanup; update the cleanup routine deleteProductsAddedByTests
(and any other functions that clear via API) to also reset the in-memory array
(e.g., productIds.length = 0 or assign a new empty array) after successful
deletion, and ensure any functions that push to productIds (the helpers that
create test products) continue to push fresh IDs; this guarantees productIds
doesn't accumulate stale IDs across test runs.
- Around line 189-228: generateVariationsFromAttributes returns inconsistent
shapes: when attributes.length === 1 it returns string[] (raw options) but for
2+ attributes it returns string[][]; also attributes[0].options will throw if
attributes is empty. Fix by normalizing the initial value and combine signature:
convert the single-attribute case into an array-of-arrays (e.g. map options to
[o]) so allVariations is always string[][], simplify combine to accept
string[][] and always return string[][], and add a guard at the start of
generateVariationsFromAttributes to handle or early-return when attributes is
empty.

Comment thread plugins/woocommerce/tests/e2e-pw/utils/wordpress.ts
Comment thread plugins/woocommerce/tests/e2e-pw/utils/wordpress.ts Outdated
@adimoldovan adimoldovan added this to the 10.7.0 milestone Feb 19, 2026
@adimoldovan adimoldovan self-requested a review February 19, 2026 10:27
@github-actions
Copy link
Copy Markdown
Contributor

Testing Guidelines

Hi @adimoldovan ,

Apart from reviewing the code changes, please make sure to review the testing instructions (Guide) and verify that relevant tests (E2E, Unit, Integration, etc.) have been added or updated as needed.

Reminder: PR reviewers are required to document testing performed. This includes:

  • 🖼️ Screenshots or screen recordings.
  • 📝 List of functionality tested / steps followed.
  • 🌐 Site details (environment attributes such as hosting type, plugins, theme, store size, store age, and relevant settings).
  • 🔍 Any analysis performed, such as assessing potential impacts on environment attributes and other plugins, conducting performance profiling, or using LLM/AI-based analysis.

⚠️ Within the testing details you provide, please ensure that no sensitive information (such as API keys, passwords, user data, etc.) is included in this public issue.

@adimoldovan adimoldovan enabled auto-merge (squash) February 19, 2026 10:56
@adimoldovan adimoldovan merged commit b39c11e into trunk Feb 19, 2026
39 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

focus: e2e tests Issues related to e2e tests plugin: woocommerce Issues related to the WooCommerce Core plugin.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants