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

Introduce snapshot testing utilities #11375

Merged
merged 18 commits into from Apr 11, 2024

Conversation

jeffsee55
Copy link
Contributor

@jeffsee55 jeffsee55 commented Apr 3, 2024

This introduces some additional capabilities on the MockClient and MockStream classes used in our unit tests.

The bulk of this code is copied over from https://github.com/SBoudrias/Inquirer.js/tree/master/packages/testing, but uses our existing stdin/stdout mocks instead of what's used there.

You can now use client.getScreen() to see the "last" screen pushed to stdin, which is super handy for snapshot tests. I've added a few as part of this PR, but many more can be written for our client output as well in the near future.


The client.getScreen() is also a handy debug tool, use it with raw: true to see a pretty printed output during tests:

Screen.Recording.2024-04-03.at.12.13.42.PM.mov

This also adds an events object on the MockClient which allows us to write client.events.keypress("down") instead of the less readable client.stdin.write('\x1B[B') throughout our testing. This could also be moved to so that it's client.stdin.keypress(... or something similar. Note that I've only tested that this works in a login test, included in this PR. If we're happy to make this change I will make update the rest of the unit tests to use this syntax for the inputs.

Copy link

changeset-bot bot commented Apr 3, 2024

🦋 Changeset detected

Latest commit: 8a1fc89

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

await expect(exitCodePromise).resolves.toEqual(0);

await expect(client.getFullOutput()).not.toContain(emoji('tip'));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When we do .not.toOutput it seems like that would guarantee that our test will wait the full 3 seconds for each one of those statements. But i wonder if we can instead just assert that the "full output" doesn't contain the string, as shown here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, .not.toOutput has to wait for a timeout, so we generally try to avoid it.

TooTallNate
TooTallNate previously approved these changes Apr 10, 2024
Copy link
Contributor

@EndangeredMassa EndangeredMassa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see type errors locally where MockStream is not compatible with WriteStream in various places. Does your IDE show any type errors in packages/cli/test/mocks/client.ts?

// This is probably fine since we don't care about those for testing; but this could become
// an issue if we ever want to test for those.
if (stripAnsi(str).trim().length > 0) {
this.#_chunks.push(str);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question (non-blocking): ‏should this push the stripped version instead of the original str?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the idea here is to determine if we should log this string. As in, if we remove any ansi sequences from the string, is there anything to show? If so, add it. And then the actual stripping is done in the getScreen call.

For context, this is copied from inquirer test https://github.com/SBoudrias/Inquirer.js/blob/master/packages/testing/src/index.mts

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohh, got it

Comment on lines 181 to 189
getScreen({ raw }: { raw?: boolean } = {}): string {
const stderr = client.stderr as any as MockStream;
const lastScreen = stderr.getLastChunk({ raw });
return raw ? lastScreen : stripAnsi(lastScreen).trim();
}
getFullOutput(): string {
const stderr = client.stderr as any as MockStream;
return stderr.getFullOutput();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (soft-blocking): if we can remove type assertions, that'd be great

When I remove this locally, it seems to work fine.

Suggested change
getScreen({ raw }: { raw?: boolean } = {}): string {
const stderr = client.stderr as any as MockStream;
const lastScreen = stderr.getLastChunk({ raw });
return raw ? lastScreen : stripAnsi(lastScreen).trim();
}
getFullOutput(): string {
const stderr = client.stderr as any as MockStream;
return stderr.getFullOutput();
}
getScreen({ raw }: { raw?: boolean } = {}): string {
const lastScreen = client.stderr.getLastChunk({ raw });
return raw ? lastScreen : stripAnsi(lastScreen).trim();
}
getFullOutput(): string {
return client.stderr.getFullOutput();
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes makes sense. I think I was trying to do some type fixes to the MockClient (that didn't work) and this was some leftover code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding the type errors, these are kind of everywhere and have been for a little while as far as I know. Not related to this PR, unless you're seeing something different. I don't think there's a great solution to fix this, have a draft PR here that I've been meaning to revisit.

TooTallNate
TooTallNate previously approved these changes Apr 11, 2024
@jeffsee55 jeffsee55 added the pr: automerge Automatically merge the PR when checks pass label Apr 11, 2024
@jeffsee55 jeffsee55 removed the pr: automerge Automatically merge the PR when checks pass label Apr 11, 2024
@jeffsee55 jeffsee55 added the pr: automerge Automatically merge the PR when checks pass label Apr 11, 2024
// it incorrectly detects that unicode is not supported,
// and thus prints ascii characters, which breaks these tests.
// https://github.com/SBoudrias/Inquirer.js/issues/1386
describe.skipIf(isWindows)('client.input', () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just skipping these on Windows

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the comment in code about this. Makes sense.

// it incorrectly detects that unicode is not supported,
// and thus prints ascii characters, which breaks these tests.
// https://github.com/SBoudrias/Inquirer.js/issues/1386
describe.skipIf(isWindows)('client.input', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the comment in code about this. Makes sense.

@kodiakhq kodiakhq bot merged commit a6f1c56 into main Apr 11, 2024
114 checks passed
@kodiakhq kodiakhq bot deleted the jeffsee55/introduce-snapshot-utilities branch April 11, 2024 19:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pr: automerge Automatically merge the PR when checks pass
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants