Ive implemented a OTP screen in my react-native project and I cant find a way to test it, I have the code for the OPT screen and I can either display the value and then tell detox to copy the text or tell it to use the state through context.
State & context:
but if I add import {useContext} from 'react' and then delcare my context const appContext = useContext(APP_CONTEXT) then use the appContext.OTPCode in my .typeText like so
await element(by.id('appOTPCode')).typeText(appContext.OTPCode);
it gives me a SyntaxError: Cannot use import statement outside a module error on import {useContext} from 'react'
is there a way to tell Detox e2e to accept such imports ?
Display OPT code on screen and copy
I cant find a way to tell detox to copy and paste the code if I display it as plain text on the screen via state.
is there a way to do something like this ?
If any of you have a solution or another way please be kind and share.
Thanks in andvance
Found a solution
it('it should enter OTP', async () => {
// get the OTP from the text field
const otp = await element(by.id('otpText')).getAttributes();
// enter the OTP into the OTP input field
await element(by.id('otpText')).tap();
await element(by.id('otpText')).typeText(otp.text);
});
Related
I am writing a puzzle app in React Native where the user can solve a puzzle by changing their device's Appearance to dark mode. I'm using React Native's Appearance module to accomplish this, by calling Appearance.getColorScheme() to get the initial color scheme, and registering an event listener for when the color scheme changes using Appearance.addChangeListener() within the useEffect hook:
useEffect(() => {
const originalColorScheme = Appearance.getColorScheme();
Appearance.addChangeListener((event) => {
if (Appearance.getColorScheme() !== originalColorScheme) {
setSolved(true);
}
});
}, []);
This is working fine, but I'd like to be able to unit test my component by simulating a change to dark mode in Jest and/or React Native Testing Library (or similar), after which I can check for changes to the content of the page (a "congratulations" message, in this case).
In my mind, it could look something like:
const text = await screen.findByText("good luck!");
// fireEvent("changeColorScheme", { colorScheme: "dark" });
const text2 = await screen.findByText("congratulations!");
Is anything like this possible? I'm guessing it has something to do with mocks, but it's a little over my head at the moment. Thanks for any help you can provide!
I'm attempting to write some tests for my react native app. A component in my app focuses a TextInput after a parent Pressable receives a press. I'm using a ref to identify and focus the TextInput element.
My desired functionality works just fine when running my app through expo, but my test is failing because it seems that the onFocus event is not being called.
Why isn't ref.current.focus() being called when running tests via the #testing-library/react-native library?
Here's my code:
Foo.js
import {Pressable, TextInput} from "react-native";
import {useRef} from "react";
const Foo = (props) => {
const inputRef = useRef()
return (
<Pressable testID={"pressable"} onPress={() => inputRef.current.focus()}>
<TextInput ref={inputRef} testID={"input"} onFocus={props.onFocus} />
</Pressable>
)
}
export default Foo;
Foo.test.js
import { render, screen, fireEvent } from '#testing-library/react-native';
import Foo from "./foo";
test('onFocus is called after press', () => {
const mockFocus = jest.fn();
render(<Foo onFocus={mockFocus} />)
// fireEvent(screen.getByTestId("input"), 'focus');
fireEvent.press(screen.getByTestId("pressable"));
expect(mockFocus).toHaveBeenCalled()
});
This test fails with the following message:
Error: expect(jest.fn()).toHaveBeenCalled()
Expected number of calls: >= 1
Received number of calls: 0
I created an issue on the RNTL GitHub page and received a response from a contributor. Copying and pasting here for easy reference for anyone who might stumble upon this thread.
This is expected as React Test Renderer which we use for rendering
does not support refs. Check #1006 for more details.
Since the behaviour of focus() triggering onFocus event would probably
involve roundtrip to native side (from JS side), then you actually
cannot test such behaviour using RNTL as we do not run native code (see
here for details).
That leaves you with following options:
Call fireEvent.focus to manually trigger onFocus on relevant
TextInput. Recommended in case focus assertion would be a part of a
step in a bigger test.
Use createNodeMock to pass ref creating function to render method, More details here. Recommended in case you
just want to assert pressing button triggers onFocus.
Is there a way to test how the page render in next.js?
Not by comparing the html, but the actual images.
So far I only found a way to "render" the component into a html (tags tree) with toJSON():
import React from 'react'
import TestRenderer from 'react-test-renderer'
import Index from './index'
it(`should render`, () => {
const testRenderer = TestRenderer.create(<Index/>)
expect(testRenderer.toJSON()).toMatchSnapshot()
})
But there is no information on how to do this with the actual rendering and real images.
At the very end I want to be able to compare the current image to the reference with pixel-perfect accuracy.
Is it possible?
You want to look for tools to do visual testing. Generally the setup is such that you run the test once, it creates screenshots, and then when you run it later again it compares against those screenshots to see if any regression occurred.
This person explains a setup with a nextJs app, cypress and applitools
I have a component that uses #stripe/stripe-react-native named NativeCheckout.
This package does not work on web (Chrome), and when I import it I get an error:
Failed to compile
/home/joey/Projects/project/project_frontend/node_modules/#stripe/stripe-react-native/lib/module/components/StripeProvider.js
Module not found: Can't resolve '../../package.json' in '/home/joey/Projects/project/project_frontend/node_modules/#stripe/stripe-react-native/lib/module/components'
So if I run it in my browser, I do not want this component. This component is only rendered on native apps. I have found three alternative ways to import the Component. If my code is working fine then I add any of the follow lines, the above error is happening. I thought this would not load in the problem code.
const loadNative = async () => {
await import("./NativeCheckout")
}
const NativeCheckout = lazy(() => import("./NativeCheckout"));
const NativeCheckout = lazy(() => import("./NativeCheckout"));
Does anyone know a way to make this work?
TIA
I am new to using code-push for react native app, Everything works okay however I want to hide the Ignore button in the dialog. I dont want the user to ignore any update I have provided, Is this possible?
From the command line, you can use the mandatory option to hide the ignore button:
# Release a mandatory update with a changelog
code-push release-react MyApp-iOS ios -m --description "Modified the header color"
If you don't want user ignore the update, then don't show the dialog at all.
Just change codePushOptions so the user always get update when open the app from background in next time:
import React from 'react';
import {
AppRegistry,
} from 'react-native';
import codePush from "react-native-code-push";
let codePushOptions = {
checkFrequency: codePush.CheckFrequency.ON_APP_RESUME,
installMode: codePush.InstallMode.ON_NEXT_RESUME,
};
import App from './app/app';
AppRegistry.registerComponent('yourApp', () => codePush(codePushOptions)(App));
To begin with it is not recommended to use UpdateDialog within your application because the App could be rejected by AppStore at all due to AppStore Review Guidelines states that
Apps must not force users to rate the app, review the app, download
other apps, or other similar actions in order to access functionality,
content, or use of the app.
So use it with care and also please see this reference for more details.
As for hiding Ignore button - you could do it providing an empty string instead of button name e.g. as follows:
CodePush.sync(
{ installMode: CodePush.InstallMode.IMMEDIATE, updateDialog: { optionalIgnoreButtonLabel: "" } }, null, null );
you can also do the same thing with the help of appcenter webview page .
you just only need to:
go into the appcenter and indside your AppOverview>>Distribute>>CodePush: .
click on setting icon and click ON on the update required btn.