@page-component-object/preset-mui provides reusable test objects for common Material UI widgets. Use them inside view test objects, Storybook play functions, and (after 0.2.x) Cypress specs via the resolver model.
| Test object | Covers |
|---|---|
MuiButtonTestObject |
Button click, disabled state |
MuiFormFieldTestObject |
TextField / FormControl by label |
MuiSelectTestObject |
Native and listbox select flows |
MuiMenuTestObject |
Menu / portal interactions |
MuiDialogTestObject |
Modal open/close |
MuiSnackbarTestObject |
Alert / snackbar text |
MuiTimePickerTestObject |
Time selection flow |
MuiTableRowTestObject |
Table row queries and cells |
MuiInputWrapperTestObject |
Shared input base |
Source: packages/presets/mui.
The preset targets MUI v5+ class names (MuiTextField-root, MuiFormControl-root, etc.) as used in apps/storybook-demo. Test against your MUI major in Storybook before adopting in production suites.
pnpm add @page-component-object/preset-mui @page-component-object/queriesPeers: react, @testing-library/react, @mui/material (in your app).
Live examples in apps/storybook-demo/src/mui/:
| Story | Demonstrates |
|---|---|
MuiPlayground.stories.tsx |
TextField, Select, Button, Snackbar, Table, TimePicker |
| Individual widget stories | Focused plays per component |
Run Storybook:
pnpm --filter @page-component-object/storybook-demo storybookimport { MuiFormFieldTestObject } from '@page-component-object/preset-mui';
import { ComponentTestObject } from '@page-component-object/queries';
const root = new ComponentTestObject(canvasElement);
const field = MuiFormFieldTestObject.getInstanceByLabel('Name', root);
await field.input.userType('Alice');
expect(field.inputValue).toBe('Alice');getInstanceByLabel walks from a parent ComponentTestObject scope — pass the story canvas or view root.
// YourView.to.tsx
export class SettingsViewTestObject extends BaseViewTestObject {
get nameField() {
return MuiFormFieldTestObject.getInstanceByLabel('Name', this);
}
async fillProfile(name: string) {
await this.nameField.input.userType(name);
await this.saveButton.userClick();
}
}Today presets use sync RTL queries on ComponentTestObject. Chainable Cypress subclasses or unified PCOContext targets are planned — see cypress-adoption.md.
Tracked in .github/PLAN.md: Autocomplete, DatePicker, Tabs, DataGrid.
- Preset authoring — portal and root policy
- Philosophy — widget intents vs domain intents
- Getting started — Level 1