Closed
Description
I have a markup that some elements visibility depends on a condition. Something like this:
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'app-test',
template: `
<form [formGroup]="formGroup">
<mat-form-field>
<mat-label>Number</mat-label>
<input matInput required formControlName="number" />
</mat-form-field>
<ng-container *ngIf="formGroup.get('number').valid">
<mat-form-field>
<mat-label>Holder</mat-label>
<input matInput required formControlName="holder" />
</mat-form-field>
<mat-form-field>
<mat-label>Expiry</mat-label>
<input matInput required formControlName="expiry" />
</mat-form-field>
<mat-form-field>
<mat-label>CVV</mat-label>
<input matInput required formControlName="cvv" />
</mat-form-field>
</ng-container>
</form>
`,
})
export class TestComponent {
readonly formGroup = this.formBuilder.group({
number: ['', [Validators.required, Validators.minlength(16), ...otherValidators]],
holder: ['', [Validators.required, Validators.minlength(5), ...otherValidators]],
expiry: ['', [Validators.required, Validators.minlength(7), ...otherValidators]],
cvv: ['', [Validators.required, Validators.minlength(3), ...otherValidators]],
});
constructor(private readonly formBuilder: FormBuilder) {}
}
//////// Test file
async function setup() {
const { rerender } = await render(TestComponent);
const numberHtmlElementRef = screen.getByRole('textbox', { name: /number/i });
const holderHtmlElementRef = screen.findByRole('textbox', { name: /holder/i });
const expiryHtmlElementRef = screen.findByRole('textbox', { name: /expiry/i });
const cvvHtmlElementRef = screen.findByRole('textbox', { name: /cvv/i });
return {
numberHtmlElementRef,
holderHtmlElementRef,
expiryHtmlElementRef,
cvvHtmlElementRef,
rerender,
} as const;
}
describe(TestComponent.name, () => {
test('someDescription', async () => {
const {
numberHtmlElementRef,
holderHtmlElementRef,
expiryHtmlElementRef,
cvvHtmlElementRef,
} = await setup();
await expect(holderHtmlElementRef).rejects.toThrow(/Unable to find/i); // ok
await expect(expiryHtmlElementRef).rejects.toThrow(/Unable to find/i); // ok
await expect(cvvHtmlElementRef).rejects.toThrow(/Unable to find/i); // ok
await userEvent.type(numberHtmlElementRef, '5353107424870314');
expect(numberHtmlElementRef).toBeValid(); // ok
await expect(holderHtmlElementRef).resolves.toBeInTheDocument(); // fail
await expect(expiryHtmlElementRef).resolves.toBeInTheDocument(); // fail
await expect(cvvHtmlElementRef).resolves.toBeInTheDocument(); // fail
// If I don't reuse the element, like this, it works (or using `queryBy`/`getBy`):
await expect(screen.findByRole('textbox', { name: /holder/i })).resolves.toBeInTheDocument(); // ok
screen.getByRole('textbox', { name: /holder/i }); // ok
});
}
So, the fields holder
, expiry
and cvv
are visible once number
is valid, but the tests keep failing. I noticed that if I query it again, using getByRole(...)
to check if it's present in document, it works, but shouldn't findByRole(...)
works in this case?
Metadata
Metadata
Assignees
Labels
No labels