Test input without label with React Testing Library - reactjs

I use react-testing-library in my application. Normally, to check if the input is in the form, we use getByLabelText. For example:
getByLabelText(/name/i)
But what if my input does not have any label? This is because of the design (UI) so I cannot have a label for the input. How can I check if that input exists in the form?

You can use the following to target a text input field.
getByRole('textbox', {name: /name/i})
More info https://testing-library.com/docs/queries/about#priority

You can also add an aria-label to your input:
<TextField inputProps={{'aria-label': "example" }} />
and then in your test:
expect(screen.getByRole("textbox", { name: "example"})).toBeInTheDocument();

If you don't know an expected text in your input, you can add "data-testid" to your input and find it like that:
<input data-testid="my-input"/>
const myInput = getByTestId('my-input');

You could add a test ID to the input that solely will be used for testing purposes.
<input data-testid="your-id" />
And in your test you would do a query rather than get as get will fail the test if the element doesn't exist at all.
expect(queryByTestId('your-id')).toBeInTheDocument()
Or you could search by display value to look for the input value
expect(queryByDisplayValue('input-value')).toBeInTheDocument()

Related

Ant design Form custom controls cannot be displayed correctly

Requirements: I want a control like the pictrue shows, checkBoxGroup to select fruit type, and every checkItem includes a InputNumber control to input count that the fruit needed.
I try to customize a form control named CheckGroup. According to the official document, I define two interfaces, value and onChange.
When I put CheckGroup in Form.Item, I get an error: TypeError: Cannot read properties of undefined (reading'map'). When I print the value in CheckGroup , it also shows undefined, but when I put CheckGroup outside the Form.Item, it can be displayed normally , and the value can also be passed successfully.
So how can I solve it? I'm not clear where the problem is.
Thanks!
Repo
props value is passed into Form.Item from the Form component and replaces the value that you specified
To correctly transfer the value, you must specify the props initialValues to the Form
<Form
layout="vertical"
initialValues={{
googds: groupData
}}
>
{/**...**/}
<Form.Item
name="googds"
label="Goods"
rules={[{ required: true, message: "Please Input Sex" }]}
>
{/**************** use like this *********************/}
<CheckGroup />
</Form.Item>
</Form>

why react hooks form with custom input first removes error and then we can type?

when the form field shows error message and I want to try to type, when it reaches the point to clear the error first it clear the error and then I am able to type.
please check this sandbox, click inside a field and then click outside it to produce the error and now try to type something for example (1111), the problem is that you have to press 1 six times to achieve 1111, I couldn't find how to solve it.
any help please?
There is a section under FAQ: https://react-hook-form.com/faqs#Whyisfirstkeystrokeisnotworking which explains which this happens. Long story short, you are mixing uncontrolled with controlled input.
You have the following option
Register:
<TextInput ref={register} name="test" defaultValue="test" /> // without value
Controller:
<Controller as={TextInput} name="test" />
https://react-hook-form.com/api#Controller
Which also contains example in the link above.

Create a mutlple email field input in react.js

I am new to react and would like to create an entry field where a user can enter multiple email address
So far, I have an email field
<TextValidator
id="email"
aria-label="email"
label="Email address used to register"
required
name="email"
value={this.state.email ? this.state.email : ""}
onChange={this.handleChange({
name: "email",
index: 0
}).bind(this)}
autoComplete="email"
margin="normal"
variant="outlined"
fullWidth
validators={["required", "isEmail"]}
errorMessages={[
"this field is required",
"email is not valid"
]}
/>
I would like either a way to enter multiple emails in the single field or maybe an add/remove button to do it.
This is want my input look like at the moment
Thanks for your help
Try React multi-email - this is exactly what you're looking for.
Here's a link to the online demo where you can check it out.
Hope this helped!
I think to achieve that, you will need a stateVariable that holds the current text being entered by the user which you keep checking to see if its a valid email or alternatively check if the next key entered is a space and if so, add it to an array of existing emails.
To display the entered emails, you will need to use an editable div and a separate component that shows a single email, then loop through entered emails and display them as components inside the mail editable div
Something like
<EditableDiv>
{ email in emails
<Email email >
}
<CurrentEntry {EmailBeingEntered} />
</EditableDiv>
The above ain't really react but just an overview of what it might look like
A simple react component to format multiple email as the user types.
Simple code
No dependency
Small size
Simple customization
demo
https://codesandbox.io/s/jpvjk8m5o9
https://www.npmjs.com/package/react-multi-email

Validations in reactJS

I am using, "formsy-react" module for validations, where I need to create different class for input type="text", type="checkbox", type="radio"
Is there any better way to achieve validations in react.
Please let me know module name and features.
A "better way" is subjective. It depends on your use case.
The simplest way to validate input data is using the HTML attribute pattern which you can read about here
For example, to only allow maximum 3 lowercase and uppercase letters without any special characters or numbers:
<input type="text" pattern="[A-Za-z]{3}" />
Another way of validating data is by using Regex (which is automatically generated with the pattern attribute stated above). But you can do it manually.
Javascript example for validating an e-mail address:
function validateEmail(email) {
var re = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(String(email).toLowerCase());
}

AngularJS text input validation with counter

I'm developing an app containing a form which has a text input with ng-model="description".
Now I want to validate this text input using ng-maxlength="50" and required. This works fine, but I also want to add a character counter (like 67/50) shown at all times. I'm using the following code to display the counter: {{description.length || 0}}/50
The issue with this, however, is that description.length doesn't return a value when it's greater than 50, because description input is invalid. In my scenario the counter would default to 0/50 when there's no input (and that's fine) but also when input exceeds max length.
I would also like to display my counter in red when the input length's invalid, but that shouldn't be too hard using angular validation css classes.
Of course I could provide custom validation, but I'm positive there's an easier solution.
Use the form element $viewValue instead like this:
<form name='form'>
<input type="text" name='description' ng-model='description' ng-maxlength="50">
{{form.description.$viewValue.length || 0}}/50
</form>
See this plunker

Resources