Problem Description
Currently, when sharing selectors/locators between adjacent steps (e.g. from .detect() to .prep()), the downstream step receives a loosely-typed lastOutcome object. Developers must manually cast the locator (e.g., lastOutcome.locator as Locator) and do not get autocomplete or type-safety on the outcome names:
.detect((page) => [
{ name: 'found', isSuccess: true, locator: page.getByRole('textbox', { name: 'Name' }) }
])
.prep('fill details', async (page, ctx, lastOutcome) => {
if (lastOutcome?.name === 'found') { // No type safety or autocomplete on 'found'
const input = lastOutcome.locator as Locator; // Requires manual cast
await input.fill('value');
}
})
Proposed Solution
Refactor the generic types of the Play builder class so that the list of outcomes provided in .detect() or .attempt() maps to a strongly-typed union. Downstream steps like .prep(), .attempt(), or .cleanup() should automatically infer:
lastOutcome.name (restricted to the literal string names defined in the prior step).
lastOutcome.locator (typed properly as Locator instead of any or unknown).
Example hypothetical signature:
class Play<
TContext = any,
TOutcomes extends { name: string; locator?: any } = any
> {
detect<const TNewOutcomes extends ReadonlyArray<OutcomeDefinition>>(
detector: (page: Page) => TNewOutcomes,
options?: DetectOptions
): Play<TContext, TNewOutcomes[number]>;
}
Problem Description
Currently, when sharing selectors/locators between adjacent steps (e.g. from
.detect()to.prep()), the downstream step receives a loosely-typedlastOutcomeobject. Developers must manually cast the locator (e.g.,lastOutcome.locator as Locator) and do not get autocomplete or type-safety on the outcome names:Proposed Solution
Refactor the generic types of the
Playbuilder class so that the list of outcomes provided in.detect()or.attempt()maps to a strongly-typed union. Downstream steps like.prep(),.attempt(), or.cleanup()should automatically infer:lastOutcome.name(restricted to the literal string names defined in the prior step).lastOutcome.locator(typed properly asLocatorinstead ofanyorunknown).Example hypothetical signature: