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

feat: implement auto preview on error #87

Merged
merged 23 commits into from May 3, 2022
Merged

feat: implement auto preview on error #87

merged 23 commits into from May 3, 2022

Conversation

nvh95
Copy link
Owner

@nvh95 nvh95 commented Apr 24, 2022

Features

  • Auto preview on test fails (experimental)
  • Update docs for autoPreview option
  • Add blog post announce new feature
  • Add to FAQ section if user experience error (undefined variable?) wants to opt-out.

Chores

  • Use node 16 for docusaurus website

@netlify
Copy link

netlify bot commented Apr 24, 2022

Deploy Preview for jest-preview-library canceled.

Name Link
🔨 Latest commit 99031d7
🔍 Latest deploy log https://app.netlify.com/sites/jest-preview-library/deploys/62715516dfb88400098a9286

@nvh95 nvh95 linked an issue Apr 24, 2022 that may be closed by this pull request
@thanhsonng thanhsonng self-assigned this Apr 27, 2022
@nvh95 nvh95 force-pushed the auto-preview branch 2 times, most recently from 68c1332 to 0462e0a Compare May 1, 2022 17:53
@nvh95 nvh95 marked this pull request as ready for review May 1, 2022 17:58
@nvh95 nvh95 requested review from ntt261298 and thanhsonng May 1, 2022 17:58
@nvh95
Copy link
Owner Author

nvh95 commented May 1, 2022

@thanhsonng Can you double-check the implementation? Also, I rebased some of your commits, so please notice if you need to push to this branch. Thanks

@nvh95
Copy link
Owner Author

nvh95 commented May 2, 2022

This implementation's currently not working yet.
Tests always pass and it does not preview the failed test automatically.
Need to investigate more.

CHANGELOG.md Outdated Show resolved Hide resolved
demo/__tests__/App.test.tsx Outdated Show resolved Hide resolved
src/configure.ts Outdated Show resolved Hide resolved
src/configure.ts Outdated Show resolved Hide resolved
src/configure.ts Outdated Show resolved Hide resolved
src/configure.ts Outdated
console.log(callback.constructor.name);
callbackWithPreview = async function () {
try {
return await (callback as () => Promise<unknown>)();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Opportunity to improve: We can write a helper function to detect an async function, that will make TypeScript happy and doesn't require type assertion here. I will add an example below.

Copy link
Owner Author

Choose a reason for hiding this comment

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

@thanhsonng I'm waiting for your example. You can commit directly as well if you want.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Turns out it is not easy to achieve. We need to inspect the return value, i.e. we must call the callback function first.
On the other hand, checking callback.constructor.name === 'AsyncFunction' is not enough IMO. We actually want to check if the function return a Promise.

So I propose something like this. We always await for callback's return value, regardless of its signature, and we make callbackWithPreview always return a Promise.

if (!callback) {
  callbackWithPreview = undefined;
} else {
  callbackWithPreview = async (...args: Parameters<jest.ProvidesCallback>) => {
    try {
      // @ts-ignore
      return await callback(...args);
    } catch (error) {
      debug();
      throw error;
    }
  }
}

Copy link
Owner Author

Choose a reason for hiding this comment

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

checking callback.constructor.name === ‘AsyncFunction’ is not enough IMO. We actually want to check if the function return a Promise.

Can you elaborate why we need to check if the function return a Promise, instead of checking the function is an async function?

So I propose something like this. We always await for callback’s return value, regardless of its signature, and we make callbackWithPreview always return a Promise.

I did try it before this and it works actually (not well tested yet). However, I have a few opening questions I haven’t had answers yet:

  1. Is there any issues regarding the rightness when we always converting sync => async?
  2. Is there any performance issues when we always use async (even when not needed)?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you elaborate why we need to check if the function return a Promise, instead of checking the function is an async function?

An async function is just syntactic sugar for functions that return a promise. Jest allows user to write functions that return a promise without using async/await syntax, so we must account for that case as well. This link is for reference: https://jestjs.io/docs/tutorial-async.

I did try it before this and it works actually (not well tested yet). However, I have a few opening questions I haven’t had answers yet:

  1. Is there any issues regarding the rightness when we always converting sync => async?
  2. Is there any performance issues when we always use async (even when not needed)?

I believe those are non-issues but you shouldn't take my words for it. I will do some research about these questions. 😂

Copy link
Owner Author

Choose a reason for hiding this comment

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

Lemme do a benchmark.

Copy link
Owner Author

@nvh95 nvh95 May 3, 2022

Choose a reason for hiding this comment

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

@thanhsonng I did a benchmark and the running time is very similar. So I will go with always async approach.

@nvh95
Copy link
Owner Author

nvh95 commented May 3, 2022

image

This implementation's currently not working yet.
Tests always pass

Since we are missing a return in line 96

and it does not preview the failed test automatically.

callback can be an async function, so just try catch is not enough, we need to await the callback and return the result. Otherwise, it never reaches catch block (line 97-100), then it never automatically preview UI if we writing something like:

it('test name', async () => {
  // Never automatic preview if test fail
})

cc: @thanhsonng

@thanhsonng thanhsonng closed this May 3, 2022
@thanhsonng thanhsonng deleted the auto-preview branch May 3, 2022 04:32
@thanhsonng thanhsonng restored the auto-preview branch May 3, 2022 04:33
@thanhsonng thanhsonng reopened this May 3, 2022
src/configure.ts Outdated Show resolved Hide resolved
src/configure.ts Show resolved Hide resolved
@nvh95 nvh95 merged commit 490757b into main May 3, 2022
@nvh95 nvh95 deleted the auto-preview branch May 3, 2022 16:17
@nvh95 nvh95 restored the auto-preview branch May 3, 2022 16:19
@nvh95 nvh95 deleted the auto-preview branch May 3, 2022 16:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Automatically snapshot on Jest error
2 participants