Overrides are opt-in so you can just expose any overridable value as a prop and run a isolated component test on it.
1,145 karma · joined March 31, 2013
Blog: http://kolodny.github.io/blog/
Linkedin: https://www.linkedin.com/in/moshekolodny
Overrides are opt-in so you can just expose any overridable value as a prop and run a isolated component test on it.
Note that if you needed a specific reference in an override there isn't a good way to get that via Playwright, consider this silly example:
it('can test spies', async () => {
const spy = browserMock.fn();
const { page } = await render(
app =>
<LogoutButtonAction.Override with={() => spy}>
{app}
<LogoutButtonAction.Override>
);
await page.getByText('Log out').click();
expect(await spy).toHaveBeenCalled();
});Not being toggle parts of the app is the root of the issue when creating e2e tests. For example overriding a feature flag, you could find the API call for the feature but what if it's a grpc call and part of your dev build pulls in any update, you can't easily change the binary response with confidence anymore.
The current solutions are good enough to do smoke tests, but nitty-gritty e2e tests don't scale well.
In the example above it's simple
export const CountdownTime = createOverride(60);
export const Countdown = () => {
const initialTime = CountdownTime.useValue();
const [time, setTime] = React.useState(initialTime);
React.useEffect(() => {
const interval = setInterval(() => {
setTime(t => t - 1);
if (t === 1) clearInterval(interval);
}, 1000);
return () => clearInterval(interval)
}, []);
return time > 0 ? <>Time left {time}</> : <>Done</>
};
it('tests faster', async () => {
const { page } = await render(
app => <CountdownTime.Override with={() => 5}>{app}</CountdownTime.Override>
);
await expect(page.getByText('Done')).not.toBeVisible();
page.waitForTimeout(5000);
await expect(page.getByText('Done')).toBeVisible();
});
If I needed something like this, I'd probably also make setInterval an override as well, so I don't need to wait at all, but you get the idea. export const Countdown = () => {
const [time, setTime] = React.useState(60);
React.useEffect(() => {
const interval = setInterval(() => {
setTime(t => t - 1);
if (t === 1) clearInterval(interval);
}, 1000);
return () => clearInterval(interval)
}, []);
return time > 0 ? <>Time left {time}</> : <>Done</>
};
Short of using Playwright Component Tests, this isn't possible.I also found an issue where the only solution was to inject sinon into the page which I wouldn't consider a great option: https://github.com/microsoft/playwright/issues/10230
$ echo -e 'this\nis\na\nwhatever foo' | nip 'return /whatever/.test(line) && cols[1]' # foohttps://www.amazon.com/Chess-Mysteries-Sherlock-Holmes-Recre...
[1][ https://raw.githubusercontent.com/casesandberg/reactcss/gh-p... ]
,
_,,)\.~,,._
(()` ``)\))),,_
| \ ''((\)))),,_ ____
|6` | ''((\())) "-.____.-" `-.-,
| .'\ ''))))' \)))
| | `. '' ((((
\, _) \/ |))))
`' | (((((
\ | ))))))
`| | ,\ /((((((
| / `-.______.< \ | )))))
| | / `. \ \ ((((
| / \ | `.\ | (((
\ | | | )| | ))
| | | | || | '
| | | | || |
| | | | || |
| | | | || |
| | | | || |
| | | | || |
| | | | || |
| | | | || |
| | | | / | |
| | /_( /_(/ /
hjw /_(/__] \_/_(
/__] /__]