profile
viewpoint
Tomas Zaicevas zaicevas @vinted Lithuania https://medium.com/@zaicevas Frontend at @vinted. Previously @wix

zaicevas/i686-os 3

Toy OS for i686 arch

zaicevas/tasm-syntax-highlighter 3

TASM Syntax highlighter for html

zaicevas/biginteger 2

BigInteger implementation in C

zaicevas/epicenter 2

Face/car recognition API (.NET core)

zaicevas/epicenter-mobile 1

A react-native (expo) app for face/car recognition

issue openedsystem-ui/theme-ui

Next.js hydration error when used with emotion

Describe the bug theme-ui does not integrate with emotion and Next.JS. Getting hydration errors.

image

To Reproduce Steps to reproduce the behavior:

  1. Bootstrap with https://github.com/lachlanjc/next-theme-starter
  2. Integrate emotion according to https://github.com/vercel/next.js/tree/canary/examples/with-emotion
  3. Run dev server
  4. See error

Reproducible repo: https://github.com/zaicevas/next-emotion-theme-ui

Expected behavior No errors

created time in 20 hours

push eventzaicevas/next-emotion-theme-ui

Tomas Zaicevas

commit sha 727b1d69d78a6a5626c89e0505d357d913282a03

Update README.md

view details

push time in 20 hours

create barnchzaicevas/next-emotion-theme-ui

branch : master

created branch time in 20 hours

created repositoryzaicevas/next-emotion-theme-ui

created time in 20 hours

issue commenttesting-library/eslint-plugin-testing-library

Report `query*` queries with wrong assertions

Ah sorry! I didn't realized the option already existed, my bad 🤦

So this should actually report query* similar to how get* is reported, not just when assertion is set right? From your description, I understood you only want to report this when this option is set, not sure if I'm missing something else.

Yes, my initial idea was to only report query* with assertion option so that we don't have situation when you're allowed to use only a specific assertion with get*, but for query* you can use any assertion:

// 'testing-library/prefer-explicit-assert': ['error', { assertion: 'toBeInTheDocument' }]
expect(screen.getByText('foo')).toBeNull() // reported because .toBeNull() is used
expect(screen.queryByText('foo')).not.toBeNull() // not reported

Not great for consistency sake ⬆️

zaicevas

comment created time in 3 days

issue commenttesting-library/eslint-plugin-testing-library

Report `query*` queries with wrong assertions

Thanks for quick response!

Why .toBeNull() is wrong but .not.toBeInTheDocument() is fine? Both are absence matchers, they both should be valid.

Because in the particular example, assertion option is set to toBeInTheDocument

Why add a new assertion option?

prefer-explicit-assert already has assertion option

zaicevas

comment created time in 3 days

issue openedtesting-library/eslint-plugin-testing-library

Report `query*` queries with wrong assertions

What rule do you want to change?

prefer-explicit-assert

Does this change cause the rule to produce more or fewer warnings?

More warnings

How will the change be implemented?

When assertion option is passed, prefer-explicit-assert will not only report get* queries that do not abide by the option, but also query* queries.

Example code

      // 'testing-library/prefer-explicit-assert': ['error', { assertion: 'toBeInTheDocument' }]
      
      // BAD:
      expect(screen.queryByText('foo')).toBeNull()
       
      // GOOD:
      expect(screen.queryByText('foo')).not.toBeInTheDocument()

How does the current rule affect the code?

Does not report query* usage.

How will the new rule affect the code?

Reports query* usage because it queries for non-existence with matcher other than toBeInTheDocument()

Anything else?

I am not sure if this deserves a new rule. However, if it was a new rule, it'd be tedious to pass the same assertion option.

Do you want to submit a pull request to change the rule?

No

created time in 4 days

PR opened testing-library/testing-library-docs

docs: remove outdated info on Jest default env

JSDOM is no longer a default environment since Jest 27: https://jestjs.io/blog/2021/05/25/jest-27#flipping-defaults

+0 -1

0 comment

1 changed file

pr created time in 5 days

push eventzaicevas/testing-library-docs

Tomas Zaicevas

commit sha 7ed1995c12e3d1e3706918fc138a391fe6eeb1ca

docs: remove outdated info on Jest default env

view details

push time in 5 days

startedAriPerkkio/eslint-remote-tester

started time in 7 days

startedtimlrx/tailwind-nextjs-starter-blog

started time in 8 days

issue commenttesting-library/eslint-plugin-testing-library

New rule suggestion: no-test-id-queries

Note that, as of now, role queries are incredibly slow for larger DOM trees (see https://github.com/testing-library/dom-testing-library/issues/552). Test ids is one of the ways to mitigate this. In my experience, certain tests are almost 1 second (!) faster with test ids, as opposed to with role queries.

maryfsc

comment created time in 12 days

issue openedtesting-library/eslint-plugin-testing-library

New rule to report document.dispatchEvent()

Name for new rule

no-document-event

Description of the new rule

I see as document.dispatchEvent(new Event('my-custom-event')) as ant anti pattern. In some cases it might require a redundant wrapping in act() because fireEvent does it out of the box.

Testing Library feature

fireEvent

Testing Library framework(s)

All

What category of rule is this?

Suggests an alternate way of doing something

Optional: other category of rule

No response

Code examples

// BAD
document.dispatchEvent(new Event('my-custom-event'))

// GOOD
fireEvent(document, new Event('my-custom-event'))

Anything else?

No response

Do you want to submit a pull request to make the new rule?

No

created time in 25 days

startedHarshCasper/Rotten-Scripts

started time in a month

issue openedtesting-library/eslint-plugin-testing-library

New rule to report selector option abuse

Name for new rule

no-empty-text

Description of the new rule

The goal of this rule is to report overly-abusive usage of selector option in Text and LabelText queries.

Example:

<div data-icon-name="x">
    <svg>
      <path />
   </svg>
</div>

can be queried with screen.getByText('', { selector: "[data-icon-name='x']" }).

However, that goes against RTL principle (The more your tests resemble the way your software is used, the more confidence they can give you) and leads to tests that depend on implementational details.

My suggestion is to report whenever getByText and getByLabelText are called with an empty string AND have selector option.

Additionally, we could think of another rule that checks whether selector is too complex. For instance, only selector: 'input' (or any other plain tag) would NOT be reported.

Testing Library feature

Text, LabelText queries + selector option https://testing-library.com/docs/queries/bylabeltext/#selector

Testing Library framework(s)

Definitely React, but I suppose it should also be related to Angular and Vue

What category of rule is this?

Suggests an alternate way of doing something

Optional: other category of rule

No response

Code examples

screen.getByLabelText('', { selector: 'input' })
screen.getByText('', { selector: 'label' })
screen.queryByLabelText('', { selector: 'input' })
screen.queryByText('', { selector: 'label' })

Anything else?

I might take this at some point, but feel free to work on this in the meantime.

Do you want to submit a pull request to make the new rule?

No

created time in a month

startedreactjs/rfcs

started time in a month

issue commenttesting-library/eslint-plugin-testing-library

`await-async-query` does not report inside waitFor

This should also be reported by prefer-find-by:

      await waitFor(() => expect(screen.getByText('I like carrots.')))
zaicevas

comment created time in 2 months

issue openedtesting-library/eslint-plugin-testing-library

`prefer-find-by` reports `querySelector`

Plugin version

4.12.4

ESLint version

7.24.0

Node.js version

14.16.0

npm/yarn version

6.14.11

Operating system

macOS Big Sur

Bug description

I expect this code snippet NOT to be reported. Furthermore, error message and auto-fix have undefined instead of a meaningful message/fix.

    it('renders', async () => {
      const { container } = render(<App />)

      await waitFor(() =>
        expect(container.querySelector("[data-icon-name='bookmark-filled']")).toBeInTheDocument(), // reported
      )
    })

Auto-fixed to: await container.findByundefined("[data-icon-name='bookmark-filled']")

Steps to reproduce

  1. Setup eslint-plugin-testing-library 4.12.4
  2. Enable prefer-find-by rule
  3. Create a test with the above code snippet
  4. Run eslint with --fix

Error output/screenshots

error  Prefer `findByundefined` query over using `waitFor` + `querySelector`  testing-library/prefer-find-by

ESLint configuration

    {
      files: ['*.test.ts', '*.test.tsx'],
      parser: '@typescript-eslint/parser',
      plugins: ['testing-library'],
      rules: {
        '@typescript-eslint/no-var-requires': 'off',
        'testing-library/prefer-find-by': 'error',
      },
    },

Rule(s) affected

prefer-find-by

Anything else?

No response

Do you want to submit a pull request to fix this bug?

No

created time in 2 months

issue commenttesting-library/eslint-plugin-testing-library

Report multiple async presence matchers

I think if there's any other code between 2 statements - we don't report.

What if is legit to await 2 elements? It could be that when a first fetch fulfills correctly, it triggers a second one and the user wants to test between those two there is a different loading message.

This wouldn't be reported.

What if there are unrelated things between the 2 presence matchers? You would have to analyze everything between the two statements.

Hm, from what I can see, we'd have to filter out comments between 2 consecutive statements and then check if these two statements are both are async presence matchers. Not sure if that'd be difficult implementationally.

What if the two statements are in the same line? Potentially, this could happen

Yep, we'd have to parse and report this.

zaicevas

comment created time in 2 months

issue openedtesting-library/eslint-plugin-testing-library

Report multiple async presence matchers

Name for new rule

single-async-query

Description of the new rule

AFAICS there's no use case when multiple async presence matchers should be used one after another. It means some of those could be refactored to .getBy and I'd argue that it's a better approach because otherwise we could use findBy* or waitFor* in all of the cases. Hence, the rule could report subsequent findBy* or waitFor that do not have anything in-between them (userEvent, jest fake timers, etc.)

Testing Library feature

Async queries

Testing Library framework(s)

React, not sure about others :)

What category of rule is this?

Suggests an alternate way of doing something

Optional: other category of rule

No response

Code examples

  it('foo bar', async () => {
    render(<AdminDishForm {...props} />)

    expect(await screen.findByText('foo')).toBeInTheDocument() // this can be omitted or queried with getByText after 'bar' appears
    expect(await screen.findByText('bar')).toBeInTheDocument()
  })

  it('foo bar waitFor', async () => {
    render(<AdminDishForm {...props} />)

    await waitFor(() => screen.getByText('foo')).toBeInTheDocument()) // this can be omitted or queried with getByText after 'bar' appears
    await waitFor(() => screen.getByText('bar)).toBeInTheDocument())
  })

Anything else?

This is up for discussion, I am not sure if I am not missing anything 😅

Do you want to submit a pull request to make the new rule?

No

created time in 2 months

issue commenttesting-library/eslint-plugin-testing-library

`await-async-query` does not report inside waitFor

Sure! Let's reopen it. Are you interested in implementing this improvement?

Ahh, missed your comment 😶 I might take care of in an unforeseeable future. In the mean time, if anyone else wants to work on it - please do so :)

zaicevas

comment created time in 2 months

issue openedfacebook/jest

[Bug]: jest.spyOn is not tracking function calls

Version

27.1.0

Steps to reproduce

  1. Open https://codesandbox.io/s/jest-spyon-is-not-tracked-skceq?file=/src/App.test.js
  2. Run tests
  3. The test fails

Expected behavior

Test shouldn't fail

Actual behavior

Test fails, because jest.spyOn(utils, "getFoo") for some reason is not tracked.

Additional context

No response

Environment

Not sure how to run it in codesandbox, but I hope the codesandbox itself is enough.

created time in 2 months

issue openedAppboy/appboy-web-sdk

`campaignId` is not typed in in-app messages

<!-- Thank you for opening an issue with Braze!

If you are experiencing issues with our product, please consider directing your issue to support@braze.com, as that is the best channel for solving integration issues. Please see the bottom for more explanation.

For other items, like requests for modifications to our SDK or bug reports, please follow the following guidelines while submitting: -->

Report

Describe your environment.

Info Value
SDK Version 3.3
Browser Affected
Affected Browser Version
Operating System Affected
Integration Method
Repro rate

What did you do?

@braze/web-sdk npm package does not type campaignId property for in app messages, even though it can be passed in constructor and it is passed when in app message is sent inside appboy.subscribeToInAppMessage(inAppMessage => console.log(inAppMessage))

created time in 2 months

issue closedAppboy/appboy-web-sdk

`instanceof` keyword does not work for in app messages

<!-- Thank you for opening an issue with Braze!

If you are experiencing issues with our product, please consider directing your issue to support@braze.com, as that is the best channel for solving integration issues. Please see the bottom for more explanation.

For other items, like requests for modifications to our SDK or bug reports, please follow the following guidelines while submitting: -->

Report

Describe your environment.

Info Value
SDK Version 3.3.0
Browser Affected Chrome
Affected Browser Version 93.0.4577.82 (Official Build) (x86_64)
Operating System Affected Mac
Integration Method CDN
Repro rate All the time

What did you do?

We integrated Braze through CDN and are using npm package for the types, as we're using TypeScript.

import Appboy from '@braze/web-sdk'

appboy.subscribeToInAppMessage(inAppMessage => {
    console.log(inAppMessage instanceof Appboy.ModalMessage)
})

What did you expect to happen?

I would expect true to be logged when modal in-app message is sent.

<!-- ℹ Please replace this with what you expected to happen. Example: Braze SDK is integrated properly and creating sessions. -->

What happened instead?

false is logged.

Steps to reproduce

  • Install Braze through npm 3.3
  • Integrate Braze by using CDN
  • Load the website
  • Programatically subscribe to in app messages as in the code snippet above
  • Send modal message

Initialization:

<script type="text/javascript">
  +function(a,p,P,b,y){a.appboy={};a.appboyQueue=[];for(var s="DeviceProperties Card Card.prototype.dismissCard Card.prototype.removeAllSubscriptions Card.prototype.removeSubscription Card.prototype.subscribeToClickedEvent Card.prototype.subscribeToDismissedEvent Banner CaptionedImage ClassicCard ControlCard ContentCards ContentCards.prototype.getUnviewedCardCount Feed Feed.prototype.getUnreadCardCount ControlMessage InAppMessage InAppMessage.SlideFrom InAppMessage.ClickAction InAppMessage.DismissType InAppMessage.OpenTarget InAppMessage.ImageStyle InAppMessage.Orientation InAppMessage.TextAlignment InAppMessage.CropType InAppMessage.prototype.closeMessage InAppMessage.prototype.removeAllSubscriptions InAppMessage.prototype.removeSubscription InAppMessage.prototype.subscribeToClickedEvent InAppMessage.prototype.subscribeToDismissedEvent FullScreenMessage ModalMessage HtmlMessage SlideUpMessage User User.Genders User.NotificationSubscriptionTypes User.prototype.addAlias User.prototype.addToCustomAttributeArray User.prototype.getUserId User.prototype.incrementCustomUserAttribute User.prototype.removeFromCustomAttributeArray User.prototype.setAvatarImageUrl User.prototype.setCountry User.prototype.setCustomLocationAttribute User.prototype.setCustomUserAttribute User.prototype.setDateOfBirth User.prototype.setEmail User.prototype.setEmailNotificationSubscriptionType User.prototype.setFirstName User.prototype.setGender User.prototype.setHomeCity User.prototype.setLanguage User.prototype.setLastKnownLocation User.prototype.setLastName User.prototype.setPhoneNumber User.prototype.setPushNotificationSubscriptionType InAppMessageButton InAppMessageButton.prototype.removeAllSubscriptions InAppMessageButton.prototype.removeSubscription InAppMessageButton.prototype.subscribeToClickedEvent display display.automaticallyShowNewInAppMessages display.destroyFeed display.hideContentCards display.showContentCards display.showFeed display.showInAppMessage display.toggleContentCards display.toggleFeed changeUser destroy getDeviceId initialize isPushBlocked isPushGranted isPushPermissionGranted isPushSupported logCardClick logCardDismissal logCardImpressions logContentCardsDisplayed logCustomEvent logFeedDisplayed logInAppMessageButtonClick logInAppMessageClick logInAppMessageHtmlClick logInAppMessageImpression logPurchase openSession registerAppboyPushMessages removeAllSubscriptions removeSubscription requestContentCardsRefresh requestFeedRefresh requestImmediateDataFlush resumeWebTracking setLogger setSdkAuthenticationSignature stopWebTracking subscribeToContentCardsUpdates subscribeToFeedUpdates subscribeToInAppMessage subscribeToNewInAppMessages subscribeToSdkAuthenticationFailures toggleAppboyLogging trackLocation unregisterAppboyPushMessages wipeData".split(" "),i=0;i<s.length;i++){for(var m=s[i],k=a.appboy,l=m.split("."),j=0;j<l.length-1;j++)k=k[l[j]];k[l[j]]=(new Function("return function "+m.replace(/\./g,"_")+"(){window.appboyQueue.push(arguments); return true}"))()}window.appboy.getCachedContentCards=function(){return new window.appboy.ContentCards};window.appboy.getCachedFeed=function(){return new window.appboy.Feed};window.appboy.getUser=function(){return new window.appboy.User};(y=p.createElement(P)).type='text/javascript';
    y.src='https://js.appboycdn.com/web-sdk/3.3/appboy.min.js';
    y.async=1;(b=p.getElementsByTagName(P)[0]).parentNode.insertBefore(y,b)
  }(window,document,'script');

  appboy.initialize(
    sdk_key
    {
      baseUrl: ...,
      enableLogging: true,
      sessionTimeoutInSeconds: 1
    }
  );

  appboy.changeUser(...);

  appboy.openSession();
</script>

closed time in 2 months

zaicevas

issue commentAppboy/appboy-web-sdk

`instanceof` keyword does not work for in app messages

Turns out I can achieve this by using this.appboy.ModalMessage as opposed to Appboy.ModalMessage. Closing.

zaicevas

comment created time in 2 months

issue openedAppboy/appboy-web-sdk

`instanceof` keyword does not work for in app messages

<!-- Thank you for opening an issue with Braze!

If you are experiencing issues with our product, please consider directing your issue to support@braze.com, as that is the best channel for solving integration issues. Please see the bottom for more explanation.

For other items, like requests for modifications to our SDK or bug reports, please follow the following guidelines while submitting: -->

Report

Describe your environment.

Info Value
SDK Version 3.3.0
Browser Affected Chrome
Affected Browser Version 93.0.4577.82 (Official Build) (x86_64)
Operating System Affected Mac
Integration Method CDN
Repro rate All the time

What did you do?

We integrated Braze through CDN and are using npm package for the types, as we're using TypeScript.

import Appboy from '@braze/web-sdk'

appboy.subscribeToInAppMessage(inAppMessage => {
    console.log(inAppMessage instanceof Appboy.ModalMessage)
})

What did you expect to happen?

I would expect true to be logged when modal in-app message is sent.

<!-- ℹ Please replace this with what you expected to happen. Example: Braze SDK is integrated properly and creating sessions. -->

What happened instead?

false is logged.

Steps to reproduce

  • Install Braze through npm 3.3
  • Integrate Braze by using CDN
  • Load the website
  • Programatically subscribe to in app messages as in the code snippet above
  • Send modal message

Initialization:

<script type="text/javascript">
  +function(a,p,P,b,y){a.appboy={};a.appboyQueue=[];for(var s="DeviceProperties Card Card.prototype.dismissCard Card.prototype.removeAllSubscriptions Card.prototype.removeSubscription Card.prototype.subscribeToClickedEvent Card.prototype.subscribeToDismissedEvent Banner CaptionedImage ClassicCard ControlCard ContentCards ContentCards.prototype.getUnviewedCardCount Feed Feed.prototype.getUnreadCardCount ControlMessage InAppMessage InAppMessage.SlideFrom InAppMessage.ClickAction InAppMessage.DismissType InAppMessage.OpenTarget InAppMessage.ImageStyle InAppMessage.Orientation InAppMessage.TextAlignment InAppMessage.CropType InAppMessage.prototype.closeMessage InAppMessage.prototype.removeAllSubscriptions InAppMessage.prototype.removeSubscription InAppMessage.prototype.subscribeToClickedEvent InAppMessage.prototype.subscribeToDismissedEvent FullScreenMessage ModalMessage HtmlMessage SlideUpMessage User User.Genders User.NotificationSubscriptionTypes User.prototype.addAlias User.prototype.addToCustomAttributeArray User.prototype.getUserId User.prototype.incrementCustomUserAttribute User.prototype.removeFromCustomAttributeArray User.prototype.setAvatarImageUrl User.prototype.setCountry User.prototype.setCustomLocationAttribute User.prototype.setCustomUserAttribute User.prototype.setDateOfBirth User.prototype.setEmail User.prototype.setEmailNotificationSubscriptionType User.prototype.setFirstName User.prototype.setGender User.prototype.setHomeCity User.prototype.setLanguage User.prototype.setLastKnownLocation User.prototype.setLastName User.prototype.setPhoneNumber User.prototype.setPushNotificationSubscriptionType InAppMessageButton InAppMessageButton.prototype.removeAllSubscriptions InAppMessageButton.prototype.removeSubscription InAppMessageButton.prototype.subscribeToClickedEvent display display.automaticallyShowNewInAppMessages display.destroyFeed display.hideContentCards display.showContentCards display.showFeed display.showInAppMessage display.toggleContentCards display.toggleFeed changeUser destroy getDeviceId initialize isPushBlocked isPushGranted isPushPermissionGranted isPushSupported logCardClick logCardDismissal logCardImpressions logContentCardsDisplayed logCustomEvent logFeedDisplayed logInAppMessageButtonClick logInAppMessageClick logInAppMessageHtmlClick logInAppMessageImpression logPurchase openSession registerAppboyPushMessages removeAllSubscriptions removeSubscription requestContentCardsRefresh requestFeedRefresh requestImmediateDataFlush resumeWebTracking setLogger setSdkAuthenticationSignature stopWebTracking subscribeToContentCardsUpdates subscribeToFeedUpdates subscribeToInAppMessage subscribeToNewInAppMessages subscribeToSdkAuthenticationFailures toggleAppboyLogging trackLocation unregisterAppboyPushMessages wipeData".split(" "),i=0;i<s.length;i++){for(var m=s[i],k=a.appboy,l=m.split("."),j=0;j<l.length-1;j++)k=k[l[j]];k[l[j]]=(new Function("return function "+m.replace(/\./g,"_")+"(){window.appboyQueue.push(arguments); return true}"))()}window.appboy.getCachedContentCards=function(){return new window.appboy.ContentCards};window.appboy.getCachedFeed=function(){return new window.appboy.Feed};window.appboy.getUser=function(){return new window.appboy.User};(y=p.createElement(P)).type='text/javascript';
    y.src='https://js.appboycdn.com/web-sdk/3.3/appboy.min.js';
    y.async=1;(b=p.getElementsByTagName(P)[0]).parentNode.insertBefore(y,b)
  }(window,document,'script');

  appboy.initialize(
    sdk_key
    {
      baseUrl: ...,
      enableLogging: true,
      sessionTimeoutInSeconds: 1
    }
  );

  appboy.changeUser(...);

  appboy.openSession();
</script>

created time in 2 months

more