74 lines
2.3 KiB
TypeScript
74 lines
2.3 KiB
TypeScript
|
|
import type {
|
||
|
|
Locator,
|
||
|
|
Page,
|
||
|
|
} from '@playwright/test';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Typography settings menu — desktop layout exposes inline ComboControls with
|
||
|
|
* increase/decrease buttons. The current value is encoded in the trigger
|
||
|
|
* button's aria-label as `${controlLabel}: ${value}` (e.g. "Size: 24").
|
||
|
|
*/
|
||
|
|
export type TypographyControl = 'size' | 'weight' | 'leading' | 'tracking';
|
||
|
|
|
||
|
|
const LABELS: Record<TypographyControl, { increase: string; decrease: string; trigger: string }> = {
|
||
|
|
size: {
|
||
|
|
increase: 'Increase Font Size',
|
||
|
|
decrease: 'Decrease Font Size',
|
||
|
|
trigger: 'Size',
|
||
|
|
},
|
||
|
|
weight: {
|
||
|
|
increase: 'Increase Font Weight',
|
||
|
|
decrease: 'Decrease Font Weight',
|
||
|
|
trigger: 'Weight',
|
||
|
|
},
|
||
|
|
leading: {
|
||
|
|
increase: 'Increase Line Height',
|
||
|
|
decrease: 'Decrease Line Height',
|
||
|
|
trigger: 'Leading',
|
||
|
|
},
|
||
|
|
tracking: {
|
||
|
|
increase: 'Increase Letter Spacing',
|
||
|
|
decrease: 'Decrease Letter Spacing',
|
||
|
|
trigger: 'Tracking',
|
||
|
|
},
|
||
|
|
};
|
||
|
|
|
||
|
|
export class TypographyMenu {
|
||
|
|
constructor(private readonly page: Page) {}
|
||
|
|
|
||
|
|
increase(control: TypographyControl): Locator {
|
||
|
|
return this.page.getByRole('button', { name: LABELS[control].increase });
|
||
|
|
}
|
||
|
|
|
||
|
|
decrease(control: TypographyControl): Locator {
|
||
|
|
return this.page.getByRole('button', { name: LABELS[control].decrease });
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Trigger button whose aria-label encodes the current value, e.g. "Size: 24".
|
||
|
|
*/
|
||
|
|
trigger(control: TypographyControl): Locator {
|
||
|
|
return this.page.getByRole('button', { name: new RegExp(`^${LABELS[control].trigger}:\\s`) });
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Parse the numeric value out of the trigger button's aria-label.
|
||
|
|
* Returns null if the label can't be read yet.
|
||
|
|
*/
|
||
|
|
async readValue(control: TypographyControl): Promise<number | null> {
|
||
|
|
const label = await this.trigger(control).getAttribute('aria-label');
|
||
|
|
if (!label) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
const match = label.match(/:\s*(-?\d+(?:\.\d+)?)/);
|
||
|
|
return match ? Number(match[1]) : null;
|
||
|
|
}
|
||
|
|
|
||
|
|
async bump(control: TypographyControl, direction: 'up' | 'down', times = 1) {
|
||
|
|
const button = direction === 'up' ? this.increase(control) : this.decrease(control);
|
||
|
|
for (let i = 0; i < times; i++) {
|
||
|
|
await button.click();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|