Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Inline snapshots #9006

Open
schickling opened this issue Sep 18, 2021 · 13 comments
Open

[Feature] Inline snapshots #9006

schickling opened this issue Sep 18, 2021 · 13 comments
Labels
feature-test-runner Playwright test specific issues P3-collecting-feedback

Comments

@schickling
Copy link

Would be great if the Playwright test runner could also support inline snapshots similar to Jest. https://jestjs.io/docs/snapshot-testing#inline-snapshots

@dgozman
Copy link
Contributor

dgozman commented Sep 18, 2021

@schickling Playwright snapshots are usually used for capturing screenshots, and inlining images into your source code seems not ideal. Do you have some other usecase in mind?

@schickling
Copy link
Author

For someone like me who's interested in using Playwright as a Jest replacement (i.e. as a test runner) this use case is quite meaningful to me but maybe there are also other use cases.

I agree that screenshots "inline" are clearly not a good fit. Maybe there's an option to add toMatchInlineTextSnapshot which indicates that this method is just meant for text(-like) data?

@dgozman
Copy link
Contributor

dgozman commented Sep 20, 2021

@schickling Makes sense. I'll leave this issue open for prioritization and to collect feedback/upvotes.

@mxschmitt mxschmitt added the feature-test-runner Playwright test specific issues label Sep 21, 2021
@sidharthv96
Copy link
Contributor

Looking at https://github.com/facebook/jest/blob/main/packages/jest-snapshot/src/InlineSnapshots.ts
New dependencies would be

  • prettier
  • @babel/traverse
  • @babel/types
  • @babel/generator

@mquandalle
Copy link

I'm also interested in this feature, but in my case having a separate “snapshot file” is preferable instead of “inlining” it. https://jestjs.io/docs/snapshot-testing#snapshot-testing-with-jest

@mquandalle
Copy link

Also we should probably rename this feature in the context of Playwright to avoid the confusion with a screenshot.

@sidharthv96
Copy link
Contributor

Storing text snapshots in a separate file is already supported.
https://playwright.dev/docs/test-snapshots

Apart from screenshots, expect(value).toMatchSnapshot(snapshotName) can also be used to compare text, png and jpeg images, or arbitrary binary data. Playwright Test auto-detects the content type and uses the appropriate comparison algorithm.

@mmkal
Copy link

mmkal commented Aug 19, 2022

Hi! I (re)wrote some of the jest inline snapshots implementation using babel and... it was a doozy. Took nearly two years and a fair few people putting a lot of hours into it persistently to get merged (not anyone's undivided attention for two years, to be fair - but it was an active PR from February 2019 to November 2020). A lot of that was complex jest dependencies, and much of the code can be borrowed from jest, but is there any way playwright could implement using typescript (that is, import * as typescript from 'typescript') instead and avoid adding babel dependencies? Just make typescript an optional peer dependency, and throw a helpful error at runtime if you try to use .toMatchInlineSnapshot() without having it installed.

Given typescript is a first class citizen. I think it's a fairly reasonable requirement that 99% of playwright users will be fine with the runner saying "if you want to use .toMatchInlineSnapshot() you have to install typescript".

Based on past experience, I think it could get really messy recursively resolving babel configs (respect all the different config file types), managing dependencies, keeping the various babel libraries in sync with each other, handling when users have different versions of babel installed, plugins, etc. etc. Plus, I suspect babel usage is (slowly) declining with the rise of tools like swc and esbuild which are strictly better (transpiling without type checking, but way faster). Types in typescript are better too (obviously!) so implementation would be pretty easy by comparison.

@vipinphogat91
Copy link

Can we have this feature in playwright please. I know we have trace which provides in-depth details but this is an important feature for any user who is not aware about playwright technical details and only wants to see the reports and snapshot for failed test steps

@ShaMan123
Copy link

I was thinking of this but with an object comparison, having snapshots exactly as jest has them, something like .toMatchObjectSnapshot - then jest has nothing to offer me and playwright wins it all.

@likun7981
Copy link

Any progress on this feature?

@ITenthusiasm
Copy link

@dgozman Another potential reason for inline snapshots: Easily evaluating JavaScript objects belonging to the browser.

Particularly, I want to verify that the entire ValidityState belonging to a given form control (and especially a Web Component that acts like a form control) has the shape that I expect as a user interacts with it. Unfortunately, the ValidityState is full of getters, which are not JSON.stringify-able. So I have to convert the object to a stringifiable object, then return that new object. I expect the object to look the same each time, so it's easier to use an inline snapshot than it is for me to keep track of individual properties myself.

/* ---------- Setup ---------- */
await renderWebComponent(page);
function getValidityStateAsJSONObject(validity: ValidityState): ValidityState {
  const object = {} as { -readonly [K in keyof ValidityState]: ValidityState[K] };
  for (const key in validity) object[key as keyof ValidityState] = validity[key as keyof ValidityState];
  return object;
}

/* ---------- Assertions ---------- */
// Before any changes
const combobox = page.getByRole("combobox");
const validityState1 = await combobox.evaluate((node, func) => {
  return eval(`${func}; getValidityStateAsJSONObject(node.validity);`);
}, getValidityStateAsJSONObject.toString());

expect(validityState1).toMatchInlineSnapshot();

// After updates to constraints
const validityState2 = await combobox.evaluate((node, func) => {
  combobox.required = true;
  return eval(`${func}; getValidityStateAsJSONObject(node.validity);`);
}, getValidityStateAsJSONObject.toString());

expect(validityState2).toMatchInlineSnapshot();

// After user interacts
await combobox.click();
await page.getByRole("option", { name: "Tenth" }).click();
const validityState3 = await combobox.evaluate((node, func) => {
  return eval(`${func}; getValidityStateAsJSONObject(node.validity);`);
}, getValidityStateAsJSONObject.toString());

expect(validityState3).toMatchInlineSnapshot();

Obviously, this is inherently an assertion on JS data, not on the visual presentation.

I'm trying to find out the cleanest ways that I can implement reusable code in Playwright. It gets really difficult when some things need to be done in browser land and some things need to be done in test runner land. (This is different from how I'd have to work in Cypress, for instance.) So anything that brings simplicity to Playwright (without being overburdensome to it) like toMatchInlineSnapshot is a big help.

@wildeyes
Copy link

wildeyes commented Mar 6, 2024

How many upvotes would make this issue considered for a next release?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-test-runner Playwright test specific issues P3-collecting-feedback
Projects
None yet
Development

No branches or pull requests