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

[RFC] Add jsx pragma integration #169

Open
rams23 opened this issue Mar 22, 2020 · 5 comments
Open

[RFC] Add jsx pragma integration #169

rams23 opened this issue Mar 22, 2020 · 5 comments
Assignees

Comments

@rams23
Copy link

rams23 commented Mar 22, 2020

Hi.
First of all thank you for the cavy library. I started using it and I was thinking if can be possible to reduce the normal code impact, removing wrap functions, useCavy, HOC etc with a jsx pragma that replaces createElement with a simple wrap.

I already executed some test and created a custom jsx function like this:

// index.js of cavy-jsx
let testStore = null;

export function setTestStore(store) {
  testStore = store;
}

export function cavyJsx(type, props, children) {

  if ('cavyTestId' in props && testStore) {
    const WrappedType = wrap(type);
    const generateTestHook = cavy(testStore);
    const newProps = {...props, ref: generateTestHook(props.cavyTestId)};
    return React.createElement(WrappedType, newProps, children);
  }

  return React.createElement.apply(undefined, arguments);
}



//index.test.js
import { setTestStore } from "cavy-jsx";

const testHookStore = new TestHookStore();

setTestStore(testHookStore);



//LoginScreen.js
/** @jsx cavyJsx */
/** @jsxFrag React.Fragment */
import { cavyJsx } from 'cavy-jsx';
...
<TextInput
          value={password}
          cavyTestId="LoginScreen.PasswordInput"
          onChangeText={setPassword}
/>
<TextInput
          value={password}
          cavyTestId="LoginScreen.PasswordInput"
          onChangeText={setPassword}
/>
<Button 
          cavyTestId="LoginScreen.Button"
          onPress={doLogin}
>
      <Text>Login</Text>
</Button>

this way the code stays clean but cavy still works and can also wrap components automatically.
I was also trying to configure @babel/plugin-transform-react-jsx to automatically inject the pragma with no success but i thing it can be feasible. The solution with the eplicit jsx pragma already works.

What do you thing?

@jalada
Copy link
Contributor

jalada commented Mar 22, 2020

@rams23 this is a really interesting approach, thank you for investigating and trying stuff out. Last time we explored this, we were looking at a possible Babel plugin but I quite like the JSX pragma idea.

We'll be exploring this further!

@rams23
Copy link
Author

rams23 commented Mar 22, 2020

Thanks for the fast reply @jalada . I'll let you know what I can find and maybe submit a PR.
The pragma is working but it must by spread everywhere. I'm trying to exploit @wordpress/babel-plugin-import-jsx-pragma and @babel/plugin-transform-react-jsx to directly inject it. Another thing that I'm trying to do is use declaration merging to add cavyTestId as default props (like children) to Component definition.

@jalada
Copy link
Contributor

jalada commented Aug 24, 2020

For anyone coming to this; see my comment on the PR for an update!

@orizens
Copy link

orizens commented Jan 6, 2021

that's a great idea @rams23
@jalada @rams23 what do you think about reusing the standard "testID" prop instead of introducing a new additional prop?
the benefit i see:

  1. not need to introduce new prop
  2. for existing code base already includes testing with react-testing or other - this would be the complementary without the need to change/add any code for adding cavy.

@jalada
Copy link
Contributor

jalada commented Jan 6, 2021

@orizens agreed, no reason why not. I'd really love one day for React Native to support querying for elements in the tree with the testID prop directly without having to build a hack like this. But in the mean time, using a pragma to get access would be an option.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants