React Native(Expo) + Appiumでe2eテスト環境を構築する（テストが通るところまで）

前回、React Native + Appiumの環境構築にチャレンジして断念したので
続きをやります。とりあえずテストは通るところまではいけた。

前回
[React Native(Expo) + Appiumでe2eテスト環境を構築する（断念）](https://qiita.com/harada4atsushi/items/cdfe6af6fc22c30db24b)

テストはtsで書きたいので、webdriverioのts型を導入する。

```
$  npm install --save-dev @wdio/types
```

テストコード。

```e2e/FirstTest.test.ts
import { remote } from "webdriverio"
import { expect, jest, test, beforeAll, afterAll } from '@jest/globals'
jest.useFakeTimers()

jest.setTimeout(60000)
let driver: WebdriverIO.Browser 

beforeAll(async () => {
  driver = await remote({
    // host: "localhost",
    port: 4723,
    waitforTimeout: 60000,
    capabilities: {
        platformName: 'iOS',
        'appium:platformVersion': '16.2',
        'appium:deviceName': 'iPhone 14',
        'appium:automationName': 'XCUITest',
        'appium:bundleId': 'com.a.harada.ExpoAppium',
    }
    // logLevel: "silent"
  });
});

afterAll(async () => {
  if (driver) {
    await driver.deleteSession();
  }
});

describe('Appium with Jest automation testing', () => {
    test('First test', async function () {
        const element = await driver.$('~TestContainer')
        // elementがエラーなく取得できること（画面に表示されていること）
        expect(element.error).toBeUndefined()
    })
})
```

アプリのコード。

```App.tsx
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container} testID="TestContainer">
      <Text>Open up App.tsx to start working on your app!</Text>
      <StatusBar style="auto" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

```

## テストを実行する

`Appium`を起動する。

```
$ npx appium
```

手動でReact Nativeアプリをビルドして起動（どうやら手動でReact Nativeのアプリを起動した状態じゃないとテストが動かない様子）。

```
$ npm run ios
```

テストを実行。

```
~/s/ExpoAppium ❯❯❯ NODE_OPTIONS=--experimental-vm-modules npx jest e2e
watchman warning:  Recrawled this watch 3 times, most recently because:
MustScanSubDirs UserDroppedTo resolve, please review the information on
https://facebook.github.io/watchman/docs/troubleshooting.html#recrawl
To clear this warning, run:
`watchman watch-del '/Users/aharada/source/ExpoAppium' ; watchman watch-project '/Users/aharada/source/ExpoAppium'`

(node:3572) ExperimentalWarning: VM Modules is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
  console.info
    2023-06-28T14:04:22.179Z INFO webdriver: Initiate new session using the WebDriver protocol

      at node_modules/@wdio/logger/build/node.js:97:9

  console.info
    2023-06-28T14:04:22.179Z INFO webdriver: [POST] http://127.0.0.1:4723/session

      at node_modules/@wdio/logger/build/node.js:97:9

  console.info
    2023-06-28T14:04:22.179Z INFO webdriver: DATA {
      capabilities: {
        alwaysMatch: {
          platformName: 'iOS',
          'appium:platformVersion': '16.2',
          'appium:deviceName': 'iPhone 14',
          'appium:automationName': 'XCUITest',
          'appium:bundleId': 'com.a.harada.ExpoAppium'
        },
        firstMatch: [ {} ]
      },
      desiredCapabilities: {
        platformName: 'iOS',
        'appium:platformVersion': '16.2',
        'appium:deviceName': 'iPhone 14',
        'appium:automationName': 'XCUITest',
        'appium:bundleId': 'com.a.harada.ExpoAppium'
      }
    }

      at node_modules/@wdio/logger/build/node.js:97:9

  console.info
    2023-06-28T14:04:22.179Z INFO webdriver: COMMAND findElement("accessibility id", "TestContainer")

      at node_modules/@wdio/logger/build/node.js:97:9

  console.info
    2023-06-28T14:04:22.179Z INFO webdriver: [POST] http://127.0.0.1:4723/session/580120cd-cc08-48ac-9e8e-d79b06b5fd34/element

      at node_modules/@wdio/logger/build/node.js:97:9

  console.info
    2023-06-28T14:04:22.179Z INFO webdriver: DATA { using: 'accessibility id', value: 'TestContainer' }

      at node_modules/@wdio/logger/build/node.js:97:9

  console.info
    2023-06-28T14:04:22.179Z INFO webdriver: RESULT {
      'element-6066-11e4-a52e-4f735466cecf': '04000000-0000-0000-3D0E-000000000000',
      ELEMENT: '04000000-0000-0000-3D0E-000000000000'
    }

      at node_modules/@wdio/logger/build/node.js:97:9

  console.info
    2023-06-28T14:04:22.179Z INFO webdriver: COMMAND deleteSession()

      at node_modules/@wdio/logger/build/node.js:97:9

  console.info
    2023-06-28T14:04:22.179Z INFO webdriver: [DELETE] http://127.0.0.1:4723/session/580120cd-cc08-48ac-9e8e-d79b06b5fd34

      at node_modules/@wdio/logger/build/node.js:97:9

  console.info
    2023-06-28T14:04:22.179Z INFO webdriver: RESULT null

      at node_modules/@wdio/logger/build/node.js:97:9

 PASS  e2e/FirstTest.test.ts
  Appium with Jest automation testing
    ✓ First test (53 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        4.754 s, estimated 5 s
```

テストが通ったああああああああ！！！！

## 終わりに

なんとかテストを実行して通るところまでは出来たけど、毎回手動で`appium`とReact Nativeビルド&起動するのはちょっとだるい。`wdio.conf.ts`を経由するやり方なら、その辺のコマンドはまとめて動いてくれた感じがするので、再度試してみたい。

## 追記: Unable to lookup in current state: Shutdown

しばらく色々いじっていたら突然謎のエラーで`run-ios`が出来なくなってしまった。何をやっても解決せず数時間ハマった。

```
$ npx react-native run-ios --simulator="iPhone 14"

...

An error was encountered processing the command (domain=com.apple.CoreSimulator.SimError, code=405):
Unable to lookup in current state: Shutdown
info Launching "jp.co.hogehoge"
error Failed to launch the app on simulator, An error was encountered processing the command (domain=com.apple.CoreSimulator.SimError, code=405):
Unable to lookup in current state: Shutdown
```

色々な解決方法がネットみつかるが、ぼくは結局iOSシミュレータをリセットしたら解決した。

iOSシミュレータを起動して、Device -> Erase ALl Content and Settingsを選択し、再び`npx react-native run-ios`を実行すると無事起動した。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47677/7aecb553-fd0a-6d57-5e2b-a58bbde7b2b4.png)

だがしかし、もう一度実行したらまた同じエラーが再現してしまった。どないやねん…