There is no iframe step. Every UI step in the shared library resolves against the scenario's main frame, so from a feature file alone the Elements fields are unreachable. There is an open issue proposing a set of frame and tab steps; none of it exists yet.
What does exist is the hook on the page object base class — frame(name) — so this is a page object away rather than blocked:
ts
@When('I enter the test card')
async enterTestCard() {
const card = this.frame('__privateStripeFrame');
await card.getByPlaceholder('1234 1234 1234 1234').fill('4242424242424242');
}
Expose one project step per meaningful action rather than a generic "switch to iframe" step — I enter the test card reads better in the feature than three frame-switching lines, and when the shared steps do arrive you replace the body and leave the feature files alone.
See page objects for how the method binds to the step.
One thing that surprised us: on Elements the number, expiry and CVC are separate iframes, so if you were hoping for one switch to the payment iframe and then three fills, that is not the shape of it. A single method that fills all three is much less annoying than three steps, and it is also the only place you have to change when the provider reorganises its frames.