0.54.2 • Published 6 months ago

@startupjs/e2e v0.54.2

Weekly downloads
-
License
-
Repository
-
Last release
6 months ago

Testing

For e2e testing on mobile platforms, uses the Detox library and test-runner Jest

Installing the package

yarn add -D @startupjs/e2e

Requirements

react: >= 16.9.0 < 17
react-native: >= 0.61.4 < 0.64.0
startupjs: >= 0.33.0-alpha.0

Running tests

To run the commands @startupjs/e2e, you need to globally install detox-cli - npm i detox-cli -g

To run testing locally, you need to run the following commands:

  • npx statrupjs test --init - will create the necessary configuration files for Detox in the root of the project (folder e2e, .detoxrc.js, .env.detox)
  • npx statrupjs test --build - build the iOS application (required in the first times or after installing new packages)
  • npx statrupjs test --ios - will run the tests in the iOS simulator. (with the flag --artifacts during tests, screenshots of the application will appear during tests in the folder /artifacts)

Writing tests

First of all, you need to read the API Detox documentation. All standard test commands can be found in this docs.

Creating a file with tests

At the e2e folder, create a file * .e2e.js and add a minimal template to it:

describe('Example', () => {
  it('should visible button', async () => {
    await x('#button').toBeVisible()
  })
})

testID

detox can find elements by id like in traditionalhtml. To assign an id to a component, pass it thetestID props with the id value. For example:

Button(
  testID='confirmButton'
  onPress=() => console.log('confirm')
) Confirm

This way we can find the given component by x('# confirmButton').

Function x

To select the required component in the application, the x function is used, it can take the following values:

  • Search by testID - must start with#, for example:x('# myButton')
  • Text search - must start with =, for example: x ('= Subscribe')
  • Search by type - just the name of the type, for example: x('UIPickerView') for Select

This feature simplifies interaction with the Detox API. It completely replaces the functions of searching for an element in the project.

Also x supports searching for nested elements. For example, we have a component with the text Test text, which is nested within a component with testID = 'parentComponent':

Div(testID='parentComponent')
  Span Test text

Then to get the component Span Test text we need to call x as follows:

await x('#parentComponent ="Test text"')

This is extremely useful in situations where the same nested elements have different parents. For example:

Div(testID='grandParent')
  Div(testID='parentComponent1')
    Span Test text
  Div(testID='parentComponent2')
    Span Test text

In this case, we have the same text in different parents. To get the Span, which is nested inparentComponent2, use:

await x('#parentComponent2 ="Test text"')

Actions

After we have found the element, we can apply some actions to it. For example, click on it, enter text, and so on. All available actions on the element can be seen in the relevant section of the Detox documentation.

Let's take a look at a few basic steps to understand how they work.

.tap()

.tap () allows you to click on an element. That is, in order to check the work, for example, of a button, you must click on it and so on. It is important to remember that this action can be applied to any element. Let's say we have a form that contains two buttons (accept and dismiss):

Div(testID='userForm')
  // any code
  Button(
    testID='acceptButton'
    onPress=() => console.log('accept')
  ) Accept
  Button(
    testID='dismissButton'
    onPress=() => console.log('dismiss')
  ) Dismiss

In order to check the behavior of the application after clicking on the Accept button, you need to do the following: 1. Find the element that matches the button Accept 2. Call the .tap method on it.

await x('#acceptButton').tap()

Thus, we have made a click on the Accept button.

.typeText(text)

.typeText (text) allows you to enter text into an element. This is necessary to check the completion of the input fields. Let's say we have a form that contains input fields:

Div(testID='userForm')
  TextInput(
    testID='userNameInput'
    label='Name'
    value=userName
    onChangeText=setUserName
  )
  TextInput(
    testID='userSurnameInput'
    label='Surname'
    value=userSurname
    onChangeText=setUserSurname
  )

Let's fill in the water fields Name and Surname.

await x('#userNameInput').typeText('Harry')
await x('#userSurnameInput').typeText('Potter')

.scroll(offset, direction, startPositionX, startPositionY)

Scrolls the element based on the passed parameters. The method is very important, because in order to find an element located below or above the current area of ​​visibility, you need to scroll until the required element appears in the visibility field.

Parameters: offset - offset for scrolling in units direction - scrolling direction (valid values: left/right/up/down) startPositionX - normalized x percentage of the item that will be used as the starting point of the scroll (optional, valid values: 0.0, 1.0, NaN - will choose the optimal value automatically, by default - NaN) startPositionY - the normalized percentage of y of the element that will be used as the starting point of the scroll (optional, valid values: 0.0, 1.0, NaN - will choose the optimal value automatically, the default is NaN)

Let's take an example. For example, we know for sure that in the form userForm, after about 100 scrolling units, the elementuserEmail that interests us will appear. The form looks like this:

Div(testID='userForm')
  // any other components
  TextInput(
    testID='userEmail'
    label='Email'
    value=userName
    onChangeText=setUserEmail
  )

Then, in order to enter text into userEmail, you first need to scroll through theuserForm element.

await x('#userForm').scroll(100, 'down')
await x('#userEmail').typeText('harryWizzard@test.com')

Expectations

After we have found the element, performed some actions, we need to check the state of the elements. For example, is the element currently visible, contains specific text, and so on. All available waits for an item can be seen in the pertinent section of the Detox documentation.

.toBeVisible()

Checks if an element is in the current scope. Thus, we can check the appearance or disappearance of elements when performing actions.

Let's say we have an openModalButton button. When you click on it, the modal window modal appears. Then the test for this behavior is:

await x('#openModalButton').tap()
await x('#modal').toBeVisible()

.toExist()

Checks if an element is on the current page (not scoping). This method is useful for simply finding out if there is an element on the page.

Let's say we have an openModalButton button. When you click on it, a long modal window modal appears and somewhere in this window there should be a change button. Then the test for this behavior is:

await x('#openModalButton').tap()
await x('#modal').toBeVisible()
await x('#change').toExist()

.toHaveToggleValue(value)

Проверяет значение переключаемых элементов(Switch или a Check-Box). Предназначен спецально для элементов которые переключаются в два положения true и false.

Пусть у нас есть элемент checkBox, изначально он должен быть false, но после нажатия на него его значение становится true. Тест выглядит так:

await x('#checkBox').toBeVisible()
await x('#checkBox').toHaveToggleValue(false)
await x('#checkBox').tap()
await x('#checkBox').toHaveToggleValue(true)

.not

A property that produces logical negation. For example, if you need to check that the invisiable element is NOT visible at the moment, then you need to write:

await x('#invisiable').not.toBeVisible()

Likewise for .toExist ().

await x('#invisiable').not.toExist()
0.55.0-alpha.1

6 months ago

0.54.1

6 months ago

0.54.2

6 months ago

0.53.0

9 months ago

0.54.0

7 months ago

0.52.1

11 months ago

0.51.0

12 months ago

0.52.0

12 months ago

0.50.13

1 year ago

0.50.12

1 year ago

0.50.5

1 year ago

0.48.0

2 years ago

0.49.0

1 year ago

0.47.0

2 years ago

0.46.0

2 years ago

0.45.0

2 years ago

0.44.0

2 years ago

0.42.0

2 years ago

0.43.0

2 years ago

0.41.2

2 years ago

0.41.0

2 years ago

0.43.1

2 years ago

0.39.11

2 years ago

0.40.0

2 years ago

0.39.0

3 years ago

0.38.0

3 years ago

0.37.0

3 years ago

0.36.0

3 years ago

0.35.10

3 years ago

0.35.2

3 years ago

0.35.0

3 years ago

0.34.0

3 years ago

0.33.1

3 years ago

0.33.0

3 years ago

0.33.0-alpha.4

3 years ago

0.33.0-alpha.2

3 years ago

0.33.0-alpha.3

3 years ago

0.33.0-alpha.0

3 years ago

0.32.1

3 years ago

0.32.0

3 years ago