Преглед изворни кода

WIP - Detox e2e for android (#2673)

* detox android support

* detox android support

* android detox fixes

* android fixes

* more android e2e fixes

* typo fix

* build fix

* remove specific test for ios

* Update DetoxTest.java

* lint fix

* fixed typo

* Update ViewController.java

* added script for android detox e2e

* detox android support

* android detox fixes

* android fixes

* more android e2e fixes

* typo fix

* build fix

* remove specific test for ios

* Update DetoxTest.java

* lint fix

* fixed typo

* Update ViewController.java

* added script for android detox e2e

* e2e test fixes

* Update Orientations.test.js

* Update ScreenStack.test.js

* Update ScreenStyle.test.js

* Update TopLevelApi.test.js
yogevbd пре 7 година
родитељ
комит
bf30cf1452
No account linked to committer's email address

+ 4
- 3
e2e/CustomTransition.js Прегледај датотеку

1
 
1
 
2
 const Utils = require('./Utils');
2
 const Utils = require('./Utils');
3
+const testIDs = require('../playground/src/testIDs');
3
 
4
 
4
-const elementByLabel = Utils.elementByLabel;
5
+const elementById = Utils.elementById;
5
 
6
 
6
 describe('custom transition', () => {
7
 describe('custom transition', () => {
7
   beforeEach(async () => {
8
   beforeEach(async () => {
9
   });
10
   });
10
 
11
 
11
   it('sanity', async () => {
12
   it('sanity', async () => {
12
-    await elementByLabel('Push Options Screen').tap();
13
-    await elementByLabel('Custom Transition').tap();
13
+    await elementById(testIDs.PUSH_OPTIONS_BUTTON).tap();
14
+    await elementById(testIDs.CUSTOM_TRANSITION_BUTTON).tap();
14
     await expect(element(by.id('shared_image1'))).toExist();
15
     await expect(element(by.id('shared_image1'))).toExist();
15
     await element(by.id('shared_image1')).tap();
16
     await element(by.id('shared_image1')).tap();
16
     await expect(element(by.id('shared_image2'))).toExist();
17
     await expect(element(by.id('shared_image2'))).toExist();

+ 11
- 16
e2e/Orientations.test.js Прегледај датотеку

9
     await device.relaunchApp();
9
     await device.relaunchApp();
10
   });
10
   });
11
 
11
 
12
-  afterEach(async () => {
13
-    await device.setOrientation('landscape');
14
-    await device.setOrientation('portrait');
15
-  });
16
-
17
   it('default allows all', async () => {
12
   it('default allows all', async () => {
18
     await elementById(testIDs.ORIENTATION_BUTTON).tap();
13
     await elementById(testIDs.ORIENTATION_BUTTON).tap();
19
     await elementById(testIDs.DEFAULT_ORIENTATION_BUTTON).tap();
14
     await elementById(testIDs.DEFAULT_ORIENTATION_BUTTON).tap();
20
-    await expect(element(by.id('currentOrientation'))).toHaveText('Portrait');
15
+    await expect(elementById(testIDs.PORTRAIT_ELEMENT)).toBeVisible();
21
     await device.setOrientation('landscape');
16
     await device.setOrientation('landscape');
22
-    await expect(element(by.id('currentOrientation'))).toHaveText('Landscape');
17
+    await expect(elementById(testIDs.LANDSCAPE_ELEMENT)).toBeVisible();
23
     await device.setOrientation('portrait');
18
     await device.setOrientation('portrait');
24
-    await expect(element(by.id('currentOrientation'))).toHaveText('Portrait');
19
+    await expect(elementById(testIDs.PORTRAIT_ELEMENT)).toBeVisible();
25
     await elementById(testIDs.DISMISS_BUTTON).tap();
20
     await elementById(testIDs.DISMISS_BUTTON).tap();
26
   });
21
   });
27
 
22
 
28
   it('landscape and portrait array', async () => {
23
   it('landscape and portrait array', async () => {
29
     await elementById(testIDs.ORIENTATION_BUTTON).tap();
24
     await elementById(testIDs.ORIENTATION_BUTTON).tap();
30
     await elementById(testIDs.LANDSCAPE_PORTRAIT_ORIENTATION_BUTTON).tap();
25
     await elementById(testIDs.LANDSCAPE_PORTRAIT_ORIENTATION_BUTTON).tap();
31
-    await expect(element(by.id('currentOrientation'))).toHaveText('Portrait');
26
+    await expect(element(by.id(testIDs.PORTRAIT_ELEMENT))).toBeVisible();
32
     await device.setOrientation('landscape');
27
     await device.setOrientation('landscape');
33
-    await expect(element(by.id('currentOrientation'))).toHaveText('Landscape');
28
+    await expect(element(by.id(testIDs.LANDSCAPE_ELEMENT))).toBeVisible();
34
     await device.setOrientation('portrait');
29
     await device.setOrientation('portrait');
35
-    await expect(element(by.id('currentOrientation'))).toHaveText('Portrait');
30
+    await expect(element(by.id(testIDs.PORTRAIT_ELEMENT))).toBeVisible();
36
     await elementById(testIDs.DISMISS_BUTTON).tap();
31
     await elementById(testIDs.DISMISS_BUTTON).tap();
37
   });
32
   });
38
 
33
 
39
   it('portrait only', async () => {
34
   it('portrait only', async () => {
40
     await elementById(testIDs.ORIENTATION_BUTTON).tap();
35
     await elementById(testIDs.ORIENTATION_BUTTON).tap();
41
     await elementById(testIDs.PORTRAIT_ORIENTATION_BUTTON).tap();
36
     await elementById(testIDs.PORTRAIT_ORIENTATION_BUTTON).tap();
42
-    await expect(element(by.id('currentOrientation'))).toHaveText('Portrait');
37
+    await expect(elementById(testIDs.PORTRAIT_ELEMENT)).toBeVisible();
43
     await device.setOrientation('landscape');
38
     await device.setOrientation('landscape');
44
-    await expect(element(by.id('currentOrientation'))).toHaveText('Portrait');
39
+    await expect(elementById(testIDs.PORTRAIT_ELEMENT)).toBeVisible();
45
     await device.setOrientation('portrait');
40
     await device.setOrientation('portrait');
46
-    await expect(element(by.id('currentOrientation'))).toHaveText('Portrait');
41
+    await expect(elementById(testIDs.PORTRAIT_ELEMENT)).toBeVisible();
47
     await elementById(testIDs.DISMISS_BUTTON).tap();
42
     await elementById(testIDs.DISMISS_BUTTON).tap();
48
   });
43
   });
49
 
44
 
51
     await elementById(testIDs.ORIENTATION_BUTTON).tap();
46
     await elementById(testIDs.ORIENTATION_BUTTON).tap();
52
     await elementById(testIDs.LANDSCAPE_ORIENTATION_BUTTON).tap();
47
     await elementById(testIDs.LANDSCAPE_ORIENTATION_BUTTON).tap();
53
     await device.setOrientation('landscape');
48
     await device.setOrientation('landscape');
54
-    await expect(element(by.id('currentOrientation'))).toHaveText('Landscape');
49
+    await expect(element(by.id(testIDs.LANDSCAPE_ELEMENT))).toBeVisible();
55
     await device.setOrientation('portrait');
50
     await device.setOrientation('portrait');
56
-    await expect(element(by.id('currentOrientation'))).toHaveText('Landscape');
51
+    await expect(element(by.id(testIDs.LANDSCAPE_ELEMENT))).toBeVisible();
57
     await elementById(testIDs.DISMISS_BUTTON).tap();
52
     await elementById(testIDs.DISMISS_BUTTON).tap();
58
   });
53
   });
59
 });
54
 });

+ 1
- 1
e2e/ScreenStack.test.js Прегледај датотеку

90
     await elementById(testIDs.SHOW_MODAL_BUTTON).tap();
90
     await elementById(testIDs.SHOW_MODAL_BUTTON).tap();
91
     await elementById(testIDs.MODAL_WITH_STACK_BUTTON).tap();
91
     await elementById(testIDs.MODAL_WITH_STACK_BUTTON).tap();
92
     await expect(elementByLabel('Screen 2')).toBeVisible();
92
     await expect(elementByLabel('Screen 2')).toBeVisible();
93
-    await Utils.tapBackIos();
93
+    await elementById(testIDs.POP_BUTTON).tap();
94
     await expect(elementByLabel('Screen 1')).toBeVisible();
94
     await expect(elementByLabel('Screen 1')).toBeVisible();
95
   });
95
   });
96
 });
96
 });

+ 3
- 11
e2e/ScreenStyle.test.js Прегледај датотеку

10
 
10
 
11
   it('declare a options on component component', async () => {
11
   it('declare a options on component component', async () => {
12
     await elementById(testIDs.PUSH_OPTIONS_BUTTON).tap();
12
     await elementById(testIDs.PUSH_OPTIONS_BUTTON).tap();
13
-    await expect(element(by.label('Static Title'))).toBeVisible();
13
+    await expect(elementByLabel('Static Title')).toBeVisible();
14
   });
14
   });
15
 
15
 
16
   it('change title on component component', async () => {
16
   it('change title on component component', async () => {
17
     await elementById(testIDs.PUSH_OPTIONS_BUTTON).tap();
17
     await elementById(testIDs.PUSH_OPTIONS_BUTTON).tap();
18
-    await expect(element(by.label('Static Title'))).toBeVisible();
18
+    await expect(elementByLabel('Static Title')).toBeVisible();
19
     await elementById(testIDs.DYNAMIC_OPTIONS_BUTTON).tap();
19
     await elementById(testIDs.DYNAMIC_OPTIONS_BUTTON).tap();
20
-    await expect(element(by.label('Dynamic Title'))).toBeVisible();
20
+    await expect(elementByLabel('Dynamic Title')).toBeVisible();
21
   });
21
   });
22
 
22
 
23
   it('set dynamic options with valid options will do something and not crash', async () => {
23
   it('set dynamic options with valid options will do something and not crash', async () => {
46
     await expect(elementById(testIDs.TOP_BAR_ELEMENT)).toBeVisible();
46
     await expect(elementById(testIDs.TOP_BAR_ELEMENT)).toBeVisible();
47
   });
47
   });
48
 
48
 
49
-  it('makes topBar transparent and opaque', async () => {
50
-    await elementByLabel('Push Options Screen').tap();
51
-    await elementByLabel('Top Bar Transparent').tap();
52
-    await expect(element(by.type('_UIVisualEffectBackdropView'))).toBeNotVisible();
53
-    await elementByLabel('Top Bar Opaque').tap();
54
-    await expect(element(by.type('_UIVisualEffectBackdropView')).atIndex(1)).toBeVisible();
55
-  });
56
-
57
   it('set Tab Bar badge on a current Tab', async () => {
49
   it('set Tab Bar badge on a current Tab', async () => {
58
     await elementById(testIDs.TAB_BASED_APP_BUTTON).tap();
50
     await elementById(testIDs.TAB_BASED_APP_BUTTON).tap();
59
     await elementById(testIDs.SET_TAB_BADGE_BUTTON).tap();
51
     await elementById(testIDs.SET_TAB_BADGE_BUTTON).tap();

+ 2
- 2
e2e/TopLevelApi.test.js Прегледај датотеку

35
   it('unmount is called on pop', async () => {
35
   it('unmount is called on pop', async () => {
36
     await elementById(testIDs.PUSH_LIFECYCLE_BUTTON).tap();
36
     await elementById(testIDs.PUSH_LIFECYCLE_BUTTON).tap();
37
     await expect(elementByLabel('didAppear')).toBeVisible();
37
     await expect(elementByLabel('didAppear')).toBeVisible();
38
-    await Utils.tapBackIos();
38
+    await elementById(testIDs.POP_BUTTON).tap();
39
     await expect(elementByLabel('componentWillUnmount')).toBeVisible();
39
     await expect(elementByLabel('componentWillUnmount')).toBeVisible();
40
-    await element(by.traits(['button']).and(by.label('OK'))).atIndex(0).tap();
40
+    await elementByLabel('OK').atIndex(0).tap();
41
     await expect(elementByLabel('didDisappear')).toBeVisible();
41
     await expect(elementByLabel('didDisappear')).toBeVisible();
42
   });
42
   });
43
 });
43
 });

+ 2
- 0
lib/android/app/src/main/java/com/reactnativenavigation/parse/TopBarOptions.java Прегледај датотеку

27
         options.drawBehind = Options.BooleanOptions.parse(json.optString("drawBehind"));
27
         options.drawBehind = Options.BooleanOptions.parse(json.optString("drawBehind"));
28
         options.rightButtons = Button.parseJsonArray(json.optJSONArray("rightButtons"));
28
         options.rightButtons = Button.parseJsonArray(json.optJSONArray("rightButtons"));
29
         options.leftButtons = Button.parseJsonArray(json.optJSONArray("leftButtons"));
29
         options.leftButtons = Button.parseJsonArray(json.optJSONArray("leftButtons"));
30
+        options.testId = TextParser.parse(json, "testID");
30
 
31
 
31
         return options;
32
         return options;
32
     }
33
     }
33
 
34
 
34
     public Text title = new NullText();
35
     public Text title = new NullText();
36
+    public Text testId = new NullText();
35
     public Color backgroundColor = new NullColor();
37
     public Color backgroundColor = new NullColor();
36
     public Color textColor = new NullColor();
38
     public Color textColor = new NullColor();
37
     public Fraction textFontSize = new NullFraction();
39
     public Fraction textFontSize = new NullFraction();

+ 1
- 0
lib/android/app/src/main/java/com/reactnativenavigation/presentation/OptionsPresenter.java Прегледај датотеку

34
         topBar.setBackgroundColor(options.backgroundColor);
34
         topBar.setBackgroundColor(options.backgroundColor);
35
         topBar.setTitleTextColor(options.textColor);
35
         topBar.setTitleTextColor(options.textColor);
36
         topBar.setTitleFontSize(options.textFontSize);
36
         topBar.setTitleFontSize(options.textFontSize);
37
+        if (options.testId.hasValue()) topBar.setTestId(options.testId.get());
37
 
38
 
38
         topBar.setTitleTypeface(options.textFontFamily);
39
         topBar.setTitleTypeface(options.textFontFamily);
39
         if (options.hidden == True) {
40
         if (options.hidden == True) {

+ 2
- 2
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/BottomTabsController.java Прегледај датотеку

69
         if (wasSelected) return false;
69
         if (wasSelected) return false;
70
         selectTabAtIndex(index);
70
         selectTabAtIndex(index);
71
         return true;
71
         return true;
72
-    }
73
-
72
+	}
73
+	
74
 	public void setTabs(final List<ViewController> tabs) {
74
 	public void setTabs(final List<ViewController> tabs) {
75
 		if (tabs.size() > 5) {
75
 		if (tabs.size() > 5) {
76
 			throw new RuntimeException("Too many tabs!");
76
 			throw new RuntimeException("Too many tabs!");

+ 4
- 0
lib/android/app/src/main/java/com/reactnativenavigation/views/TopBar.java Прегледај датотеку

51
         return titleBar.getTitle() != null ? titleBar.getTitle().toString() : "";
51
         return titleBar.getTitle() != null ? titleBar.getTitle().toString() : "";
52
     }
52
     }
53
 
53
 
54
+    public void setTestId(String testId) {
55
+        setTag(testId);
56
+    }
57
+
54
     public void setTitleTextColor(Color color) {
58
     public void setTitleTextColor(Color color) {
55
         if (color.hasValue()) titleBar.setTitleTextColor(color.get());
59
         if (color.hasValue()) titleBar.setTitleTextColor(color.get());
56
     }
60
     }

+ 13
- 0
package.json Прегледај датотеку

38
     "test-unit-ios": "node ./scripts/test.unit.ios.js",
38
     "test-unit-ios": "node ./scripts/test.unit.ios.js",
39
     "pretest-e2e-android": "npm run build",
39
     "pretest-e2e-android": "npm run build",
40
     "test-e2e-android": "node ./scripts/test.e2e.android.js",
40
     "test-e2e-android": "node ./scripts/test.e2e.android.js",
41
+    "test-e2e-android-detox": "node ./scripts/test.e2e.android.detox.js",
41
     "pretest-e2e-ios": "npm run build",
42
     "pretest-e2e-ios": "npm run build",
42
     "test-e2e-ios": "node ./scripts/test.e2e.ios.js",
43
     "test-e2e-ios": "node ./scripts/test.e2e.ios.js",
43
     "test-all": "node ./scripts/test.all.js",
44
     "test-all": "node ./scripts/test.all.js",
123
         "build": "RCT_NO_LAUNCH_PACKAGER=true xcodebuild build -scheme playground_release -project playground/ios/playground.xcodeproj -sdk iphonesimulator -configuration Release -derivedDataPath playground/ios/DerivedData/playground ONLY_ACTIVE_ARCH=YES -quiet",
124
         "build": "RCT_NO_LAUNCH_PACKAGER=true xcodebuild build -scheme playground_release -project playground/ios/playground.xcodeproj -sdk iphonesimulator -configuration Release -derivedDataPath playground/ios/DerivedData/playground ONLY_ACTIVE_ARCH=YES -quiet",
124
         "type": "ios.simulator",
125
         "type": "ios.simulator",
125
         "name": "iPhone SE"
126
         "name": "iPhone SE"
127
+      },
128
+      "android.emu.debug": {
129
+        "binaryPath": "playground/android/app/build/outputs/apk/debug/app-debug.apk",
130
+        "build": "cd playground/android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug && cd ../..",
131
+        "type": "android.emulator",
132
+        "name": "Nexus_5X_API_26"
133
+      },
134
+      "android.emu.release": {
135
+        "binaryPath": "playground/android/app/build/outputs/apk/release/app-release.apk",
136
+        "build": "cd playground/android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release && cd ../..",
137
+        "type": "android.emulator",
138
+        "name": "Nexus_5X_API_26"
126
       }
139
       }
127
     }
140
     }
128
   }
141
   }

+ 9
- 0
playground/android/app/build.gradle Прегледај датотеку

25
         ndk {
25
         ndk {
26
             abiFilters "armeabi-v7a", "x86"
26
             abiFilters "armeabi-v7a", "x86"
27
         }
27
         }
28
+
29
+        testBuildType System.getProperty('testBuildType', 'debug')  //this will later be used to control the test apk build type
30
+        missingDimensionStrategy "minReactNative", "minReactNative46" //read note
31
+        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
28
     }
32
     }
29
     signingConfigs {
33
     signingConfigs {
30
         release {
34
         release {
47
     implementation 'com.android.support:design:25.4.0'
51
     implementation 'com.android.support:design:25.4.0'
48
     implementation "com.android.support:appcompat-v7:25.4.0"
52
     implementation "com.android.support:appcompat-v7:25.4.0"
49
     implementation project(':react-native-navigation')
53
     implementation project(':react-native-navigation')
54
+
55
+    androidTestImplementation(project(path: ":detox"))
56
+    androidTestImplementation 'junit:junit:4.12'
57
+    androidTestImplementation 'com.android.support.test:runner:1.0.1'
58
+    androidTestImplementation 'com.android.support.test:rules:1.0.1'
50
 }
59
 }

+ 24
- 0
playground/android/app/src/androidTest/java/com/reactnativenavigation/playground/DetoxTest.java Прегледај датотеку

1
+package com.reactnativenavigation.playground;
2
+
3
+import android.support.test.filters.LargeTest;
4
+import android.support.test.rule.ActivityTestRule;
5
+import android.support.test.runner.AndroidJUnit4;
6
+
7
+import com.wix.detox.Detox;
8
+
9
+import org.junit.Rule;
10
+import org.junit.Test;
11
+import org.junit.runner.RunWith;
12
+
13
+@RunWith(AndroidJUnit4.class)
14
+@LargeTest
15
+public class DetoxTest {
16
+
17
+    @Rule
18
+    public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class, false, false);
19
+
20
+    @Test
21
+    public void runDetoxTests() throws InterruptedException {
22
+        Detox.runTests(mActivityRule);
23
+    }
24
+}

+ 3
- 0
playground/android/settings.gradle Прегледај датотеку

3
 include ':app'
3
 include ':app'
4
 include ':react-native-navigation'
4
 include ':react-native-navigation'
5
 project(':react-native-navigation').projectDir = new File(rootProject.projectDir, '../../lib/android/app/')
5
 project(':react-native-navigation').projectDir = new File(rootProject.projectDir, '../../lib/android/app/')
6
+
7
+include ':detox'
8
+project(':detox').projectDir = new File(rootProject.projectDir, '../../node_modules/detox/android/detox')

+ 5
- 0
playground/src/screens/LifecycleScreen.js Прегледај датотеку

37
         <Text style={styles.h1}>{`Lifecycle Screen`}</Text>
37
         <Text style={styles.h1}>{`Lifecycle Screen`}</Text>
38
         <Text style={styles.h1}>{this.state.text}</Text>
38
         <Text style={styles.h1}>{this.state.text}</Text>
39
         <Button title='Push to test didDisappear' testID={testIDs.PUSH_TO_TEST_DID_DISAPPEAR_BUTTON} onPress={this.onClickPush} />
39
         <Button title='Push to test didDisappear' testID={testIDs.PUSH_TO_TEST_DID_DISAPPEAR_BUTTON} onPress={this.onClickPush} />
40
+        <Button title='Pop' testID={testIDs.POP_BUTTON} onPress={() => this.onClickPop()} />
40
         <Text style={styles.footer}>{`this.props.componentId = ${this.props.componentId}`}</Text>
41
         <Text style={styles.footer}>{`this.props.componentId = ${this.props.componentId}`}</Text>
41
       </View>
42
       </View>
42
     );
43
     );
45
   onClickPush() {
46
   onClickPush() {
46
     Navigation.push(this.props.componentId, { component: { name: 'navigation.playground.TextScreen' } });
47
     Navigation.push(this.props.componentId, { component: { name: 'navigation.playground.TextScreen' } });
47
   }
48
   }
49
+
50
+  onClickPop() {
51
+    Navigation.pop(this.props.componentId);
52
+  }
48
 }
53
 }
49
 module.exports = LifecycleScreen;
54
 module.exports = LifecycleScreen;
50
 
55
 

+ 1
- 1
playground/src/screens/OptionsScreen.js Прегледај датотеку

63
         <Button title='Top Bar Transparent' onPress={this.onClickTopBarTransparent} />
63
         <Button title='Top Bar Transparent' onPress={this.onClickTopBarTransparent} />
64
         <Button title='Top Bar Opaque' onPress={this.onClickTopBarOpaque} />
64
         <Button title='Top Bar Opaque' onPress={this.onClickTopBarOpaque} />
65
         <Button title='scrollView Screen' testID={testIDs.SCROLLVIEW_SCREEN_BUTTON} onPress={this.onClickScrollViewScreen} />
65
         <Button title='scrollView Screen' testID={testIDs.SCROLLVIEW_SCREEN_BUTTON} onPress={this.onClickScrollViewScreen} />
66
-        <Button title='Custom Transition' onPress={this.onClickCustomTranstition} />
66
+        <Button title='Custom Transition' testID={testIDs.CUSTOM_TRANSITION_BUTTON} onPress={this.onClickCustomTranstition} />
67
         <Button title='Show custom alert' testID={testIDs.SHOW_CUSTOM_ALERT_BUTTON} onPress={this.onClickAlert} />
67
         <Button title='Show custom alert' testID={testIDs.SHOW_CUSTOM_ALERT_BUTTON} onPress={this.onClickAlert} />
68
         <Button title='Show snackbar' testID={testIDs.SHOW_SNACKBAR_BUTTON} onPress={this.onClickSnackbar} />
68
         <Button title='Show snackbar' testID={testIDs.SHOW_SNACKBAR_BUTTON} onPress={this.onClickSnackbar} />
69
         <Button title='Show overlay' testID={testIDs.SHOW_OVERLAY_BUTTON} onPress={() => this.onClickShowOverlay(true)} />
69
         <Button title='Show overlay' testID={testIDs.SHOW_OVERLAY_BUTTON} onPress={() => this.onClickShowOverlay(true)} />

+ 3
- 1
playground/src/screens/OrientationDetectScreen.js Прегледај датотеку

23
         <Text style={styles.h1}>{`Orientation Screen`}</Text>
23
         <Text style={styles.h1}>{`Orientation Screen`}</Text>
24
         <Button title='Dismiss' testID={testIDs.DISMISS_BUTTON} onPress={() => Navigation.dismissModal(this.props.componentId)} />
24
         <Button title='Dismiss' testID={testIDs.DISMISS_BUTTON} onPress={() => Navigation.dismissModal(this.props.componentId)} />
25
         <Text style={styles.footer}>{`this.props.componentId = ${this.props.componentId}`}</Text>
25
         <Text style={styles.footer}>{`this.props.componentId = ${this.props.componentId}`}</Text>
26
-        <Text style={styles.footer} testID='currentOrientation'>{this.state.horizontal ? 'Landscape' : 'Portrait'}</Text>
26
+        {this.state.horizontal ?
27
+        <Text style={styles.footer} testID={testIDs.LANDSCAPE_ELEMENT}>Landscape</Text> :
28
+        <Text style={styles.footer} testID={testIDs.PORTRAIT_ELEMENT}>Portrait</Text>}
27
       </View>
29
       </View>
28
     );
30
     );
29
   }
31
   }

+ 4
- 8
playground/src/screens/OrientationSelectScreen.js Прегледај датотеку

1
 const React = require('react');
1
 const React = require('react');
2
 const { Component } = require('react');
2
 const { Component } = require('react');
3
+
3
 const { View, Text, Button } = require('react-native');
4
 const { View, Text, Button } = require('react-native');
4
 
5
 
5
 const { Navigation } = require('react-native-navigation');
6
 const { Navigation } = require('react-native-navigation');
6
 const testIDs = require('../testIDs');
7
 const testIDs = require('../testIDs');
7
 
8
 
8
 class OrientationSelectScreen extends Component {
9
 class OrientationSelectScreen extends Component {
9
-
10
   render() {
10
   render() {
11
     return (
11
     return (
12
       <View style={styles.root}>
12
       <View style={styles.root}>
37
   root: {
37
   root: {
38
     flexGrow: 1,
38
     flexGrow: 1,
39
     justifyContent: 'center',
39
     justifyContent: 'center',
40
-    alignItems: 'center'
40
+    alignItems: 'center',
41
+    backgroundColor: '#f5fcff'
41
   },
42
   },
42
   h1: {
43
   h1: {
43
     fontSize: 24,
44
     fontSize: 24,
44
     textAlign: 'center',
45
     textAlign: 'center',
45
-    margin: 30
46
-  },
47
-  footer: {
48
-    fontSize: 10,
49
-    color: '#888',
50
-    marginTop: 10
46
+    margin: 10
51
   }
47
   }
52
 };
48
 };

+ 4
- 0
playground/src/screens/TextScreen.js Прегледај датотеку

97
       }
97
       }
98
     });
98
     });
99
   }
99
   }
100
+
101
+  onClickPop() {
102
+    Navigation.pop(this.props.componentId);
103
+  }
100
 }
104
 }
101
 
105
 
102
 module.exports = TextScreen;
106
 module.exports = TextScreen;

+ 3
- 0
playground/src/testIDs.js Прегледај датотеку

51
   SHOW_TOUCH_THROUGH_OVERLAY_BUTTON: `SHOW_TOUCH_THROUGH_OVERLAY_BUTTON`,
51
   SHOW_TOUCH_THROUGH_OVERLAY_BUTTON: `SHOW_TOUCH_THROUGH_OVERLAY_BUTTON`,
52
   OK_BUTTON: `OK_BUTTON`,
52
   OK_BUTTON: `OK_BUTTON`,
53
   MODAL_WITH_STACK_BUTTON: `MODAL_WITH_STACK_BUTTON`,
53
   MODAL_WITH_STACK_BUTTON: `MODAL_WITH_STACK_BUTTON`,
54
+  CUSTOM_TRANSITION_BUTTON: `CUSTOM_TRANSITION_BUTTON`,
54
 
55
 
55
   // Elements
56
   // Elements
56
   SCROLLVIEW_ELEMENT: `SCROLLVIEW_ELEMENT`,
57
   SCROLLVIEW_ELEMENT: `SCROLLVIEW_ELEMENT`,
57
   BOTTOM_TABS_ELEMENT: `BOTTOM_TABS_ELEMENT`,
58
   BOTTOM_TABS_ELEMENT: `BOTTOM_TABS_ELEMENT`,
58
   TOP_BAR_ELEMENT: `TOP_BAR_ELEMENT`,
59
   TOP_BAR_ELEMENT: `TOP_BAR_ELEMENT`,
60
+  LANDSCAPE_ELEMENT: `LANDSCAPE_ELEMENT`,
61
+  PORTRAIT_ELEMENT: `PORTRAIT_ELEMENT`,
59
 
62
 
60
   // Headers
63
   // Headers
61
   WELCOME_SCREEN_HEADER: `WELCOME_SCREEN_HEADER`,
64
   WELCOME_SCREEN_HEADER: `WELCOME_SCREEN_HEADER`,

+ 12
- 0
scripts/test.e2e.android.detox.js Прегледај датотеку

1
+const _ = require('lodash');
2
+const exec = require('shell-utils').exec;
3
+
4
+const release = _.includes(process.argv, '--release');
5
+
6
+run();
7
+
8
+function run() {
9
+  const conf = release ? `release` : `debug`;
10
+  exec.execSync(`detox build --configuration android.emu.${conf}`);
11
+  exec.execSync(`detox test --configuration android.emu.${conf} ${process.env.CI ? '--cleanup' : ''}`);
12
+}