Skip to content

Commit

Permalink
Add optional
Browse files Browse the repository at this point in the history
  • Loading branch information
RoyalIcing committed Feb 2, 2024
1 parent 4aec8d2 commit 012e9e5
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 11 deletions.
5 changes: 4 additions & 1 deletion src/resolver.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { screen, waitFor } from '@testing-library/dom';
import user from '@testing-library/user-event';
import { AllDescriptor, RoleDescriptor } from './roles/types';
import { AllDescriptor, RoleDescriptor, optional } from './roles/types';

export type DescriptorResult<T> = T extends RoleDescriptor & AllDescriptor
? Array<HTMLElement>
Expand Down Expand Up @@ -33,6 +33,9 @@ export function resolverFor(
if ('all' in descriptor && descriptor.all === true) {
const { name } = descriptor;
return source.queryAllByRole(descriptor.role, { name }) as any;
} else if (optional in descriptor) {
const { name, isSelected: selected } = descriptor;
return source.queryByRole(descriptor.role, { name, selected }) as any;
} else {
const { name, isSelected: selected } = descriptor;
return source.getByRole(descriptor.role, { name, selected });
Expand Down
4 changes: 4 additions & 0 deletions src/roles/combobox.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ describe('Combobox', () => {
expect(screenTest(Combobox())).toBeVisible();
});

it('hides listbox', () => {
expect(screenTest(Combobox.PopupListbox().optional)).toBeNull();
});

it('renders named combobox', () => {
expect(screenTest(Combobox('Person'))).toBeVisible();
});
Expand Down
21 changes: 14 additions & 7 deletions src/roles/shared.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
import { prettyDOM } from '@testing-library/dom';
import type { AllDescriptor, RoleDescriptor } from './types';
import { optional, type AllDescriptor, type RoleDescriptor } from './types';

export type RoleObject<SupportedEvent extends { click?: true }> = {
role: string;
export type RoleObject<
Role extends string,
SupportedEvent extends { click?: true }
> = {
role: Role;
name?: string | RegExp;
optional: RoleObject<Role, SupportedEvent>;
all: RoleDescriptor & AllDescriptor;
} & (SupportedEvent['click'] extends true
? {
click: RoleDescriptor;
}
: {});

export function role<SupportedEvent extends { click?: true }>(
role: string,
name?: string | RegExp
): RoleObject<SupportedEvent> {
export function role<
Role extends string,
SupportedEvent extends { click?: true }
>(role: Role, name?: string | RegExp): RoleObject<Role, SupportedEvent> {
return Object.freeze({
role,
name,
get all(): RoleDescriptor & AllDescriptor {
return Object.create(this, { all: { value: true } });
},
get optional() {
return Object.create(this, { [optional]: { value: true } });
},
get click(): RoleDescriptor {
return Object.create(this, { event: { value: 'click' } });
},
Expand Down
7 changes: 4 additions & 3 deletions src/roles/types.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import { queries, BoundFunctions, Queries } from '@testing-library/dom';

const all = Symbol('all');
export const optional = Symbol('optional');

export interface RoleDescriptor {
readonly role: string;
readonly name?: string | RegExp;
readonly [optional]?: true;
readonly isSelected?: boolean;
// readonly all?: true;
readonly event?: 'click';
}

export interface AllDescriptor {
readonly all: true;
}

export interface AllRoleDescription extends RoleDescriptor, AllDescriptor {}

export interface SingleDescriptor<Q extends Queries = typeof queries> {
get(source: BoundFunctions<Q>): HTMLElement;
}

0 comments on commit 012e9e5

Please sign in to comment.