Skip to content

Commit f077f84

Browse files
authored
E2E Tests setup for Android (#2399)
* Basic E2E setup for android * Basic tests working * Added scrolling element selector to Android * Cleanup code * Change files * Replace ScrollView id with existing const * Clean up mobile scroll * Testing Android pipeline * Fix platform * Fix spacing * Changing Gradlew task * Comment non-android tests * Changed vm to ubuntu added working directory to gradlew * Update emulator to use xamarin * Updated fradlew task * Revert ubuntu change for Android PR * Revert "Update emulator to use xamarin" This reverts commit 6bea0a8. * Change jdk path * Update version for jdk * Disable yarn android * Revert "Disable yarn android" This reverts commit 1dc6bad. * Set to re-install apk mode * Remove existing packages * Remove yarn android, add caching for avd * Added apk dump mechanism * Fix syntax * Fix syntax * Fix syntax * Update apk dump to run on failure * Testing screenshot on android * Update emulator script * Fix missing label for E2E * Reverting APK dump mechanism * Attempting to fix screenshot issue * Attempting to fix screenshot issue x2 * Attempting to fix screenshot issue x3 * Attempting to fix screenshot issue x4 * Revert "Attempting to fix screenshot issue x4" This reverts commit f6ed8fd. * Change to MacOS 12 * Revert "Change to MacOS 12" This reverts commit 7cdaacd. * Attempting to fix screenshot issue x5 * Revert "Comment non-android tests" This reverts commit d4faed2. * Revert "Testing screenshot on android" This reverts commit 88cde98. * Added apk dump on failure * Code cleanup * Test Screenshot * Change emulator device model and Remove apk dump * Revert "Test Screenshot" This reverts commit 3deb823. * Replace testId with testProps * Attempt AVD Caching * Fix task blocks * Fix import * Revert AVD Caching * Revert "Revert AVD Caching" This reverts commit f31ac5a. * Try different path * Path format fix * Change path to single folder * Enable quick boot emulator * Revert "Enable quick boot emulator" This reverts commit e50cfa9. * Removing caching * Code cleanup * Resolve comments * Resolve comments * Remove extra bundle command from E2E
1 parent 2b96183 commit f077f84

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1072
-126
lines changed

.ado/azure-pipelines.yml

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,8 @@ jobs:
6161
# sets-up specifics for android dependency like NDK & emulator
6262
- template: templates/android-dep-setup.yml
6363

64-
- bash: |
65-
echo "yarn $(platform)"
66-
yarn $(platform)
67-
workingDirectory: apps/fluent-tester
68-
displayName: 'yarn $(platform)'
69-
env:
70-
JAVA_HOME: $(JAVA_HOME_11_X64)
71-
PATH: $(JAVA_HOME_11_X64)/bin;$(PATH)
64+
# builds a debug apk and runs E2E tests on it
65+
- template: templates/e2e-testing-android.yml
7266

7367
- job: macOSPR
7468
displayName: macOS PR

.ado/templates/android-dep-setup.yml

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,41 @@ steps:
77
#!/usr/bin/env bash
88
99
# Install AVD files
10-
echo "y" | $ANDROID_HOME/tools/bin/sdkmanager --install 'system-images;android-27;google_apis;x86'
10+
echo "y" | $ANDROID_HOME/tools/bin/sdkmanager --install 'system-images;android-27;default;x86_64'
1111
1212
# Create emulator
13-
echo "no" | $ANDROID_HOME/tools/bin/avdmanager create avd -n android_emulator -k 'system-images;android-27;google_apis;x86' --force
13+
echo "no" | $ANDROID_HOME/tools/bin/avdmanager create avd -n android_emulator -d 19 --package 'system-images;android-27;default;x86_64'
1414
1515
# list emulator
1616
echo "Available emulator"
1717
$ANDROID_HOME/emulator/emulator -list-avds
1818
19+
if false; then
20+
emulator_config=~/.android/avd/android_emulator.avd/config.ini
21+
# The following is to support empty OR populated config.ini files,
22+
# the state of which is dependant on the version of the emulator used (which we don't control),
23+
# Replace existing config (NOTE we're on MacOS so sed works differently!)
24+
sed -i .bak 's/hw.lcd.density=.*/hw.lcd.density=420/' "$emulator_config"
25+
sed -i .bak 's/hw.lcd.height=.*/hw.lcd.height=1920/' "$emulator_config"
26+
sed -i .bak 's/hw.lcd.width=.*/hw.lcd.width=1080/' "$emulator_config"
27+
# Or, add new config
28+
if ! grep -q "hw.lcd.density" "$emulator_config"; then
29+
echo "hw.lcd.density=420" >> "$emulator_config"
30+
fi
31+
if ! grep -q "hw.lcd.height" "$emulator_config"; then
32+
echo "hw.lcd.height=1920" >> "$emulator_config"
33+
fi
34+
if ! grep -q "hw.lcd.width" "$emulator_config"; then
35+
echo "hw.lcd.width=1080" >> "$emulator_config"
36+
fi
37+
echo "Emulator settings ($emulator_config)"
38+
cat "$emulator_config"
39+
fi
40+
1941
echo "Starting emulator"
2042
2143
# Start emulator in background
22-
nohup $ANDROID_HOME/emulator/emulator -avd android_emulator -no-snapshot > /dev/null 2>&1 &
44+
nohup $ANDROID_HOME/emulator/emulator -avd android_emulator -no-snapshot -no-audio -gpu host -no-boot-anim -qemu -m 2048 > /dev/null 2>&1 &
2345
$ANDROID_HOME/platform-tools/adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed | tr -d '\r') ]]; do sleep 1; done; input keyevent 82'
2446
2547
#list online device/emulator
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
steps:
2+
# Building APK also requires bundling, this is currently already being done as part of main Android PR task.
3+
- task: Gradle@2
4+
displayName: 'gradlew build apk'
5+
inputs:
6+
gradleWrapperFile: 'apps/fluent-tester/android/gradlew'
7+
tasks: 'assembleDebug'
8+
gradleOptions: '-Xmx2g'
9+
javaHomeOption: 'JDKVersion'
10+
jdkVersionOption: '1.11'
11+
workingDirectory: apps/fluent-tester/android
12+
13+
- script: |
14+
adb install app-debug.apk
15+
workingDirectory: apps/fluent-tester/android/app/build/outputs/apk/debug
16+
displayName: 'install apk'
17+
18+
# Creates a variable that determines whether the previous build tasks succeeded.
19+
# Usage: We want the tasks that generate reports to run for both passing/failing E2E testing tasks. In order to do so, we need to make
20+
# those reporting tasks run even on when certain previous tasks fail. This variable allows us to differentiate build failures from
21+
# E2E testing failures. Thus, if this variable != "Success", we know the build failed, and to not run the reporting tasks.
22+
- task: PowerShell@2
23+
inputs:
24+
targetType: 'inline'
25+
script: |
26+
Write-Host "##vso[task.setvariable variable=task.Build.status]Success"
27+
condition: succeeded()
28+
displayName: 'Create success build variable'
29+
30+
- script: |
31+
yarn e2etest:android
32+
workingDirectory: apps/E2E
33+
displayName: 'run E2E Android tests'
34+
condition: succeeded()
35+
36+
- template: e2e-publish-artifacts.yml
37+
parameters:
38+
applicationType: android
39+
platform: 'android'
40+
buildArtifacts: variables['task.Build.status']
41+
directory: $(Build.SourcesDirectory)/apps/E2E

apps/E2E/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"license": "MIT",
66
"scripts": {
77
"build": "fluentui-scripts build",
8+
"e2etest:android": "wdio run wdio.conf.android.js",
89
"e2etest:ios": "wdio run wdio.conf.ios.js",
910
"e2etest:macos": "wdio run wdio.conf.macos.js",
1011
"e2etest:windows": "rimraf errorShots/* reports/* && wdio run wdio.conf.windows.js"
@@ -40,6 +41,7 @@
4041
"appium-mac2-driver": "1.4.0",
4142
"appium-windows-driver": "2.0.7",
4243
"appium-xcuitest-driver": "4.11.1",
44+
"appium-uiautomator2-driver": "^2.10.2",
4345
"@babel/core": "^7.8.0",
4446
"@babel/runtime": "^7.8.0",
4547
"@fluentui-react-native/focus-zone": "^0.11.18"

apps/E2E/src/Avatar/pages/AvatarPageObject.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ class AvatarPageObject extends BasePage {
1717
return By(HOMEPAGE_AVATAR_BUTTON);
1818
}
1919

20+
get _pageButtonName() {
21+
return HOMEPAGE_AVATAR_BUTTON;
22+
}
23+
2024
get _pageName() {
2125
return AVATAR_TESTPAGE;
2226
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import NavigateAppPage from '../../common/NavigateAppPage';
2+
import AvatarPageObject from '../pages/AvatarPageObject';
3+
import { PAGE_TIMEOUT, BOOT_APP_TIMEOUT } from '../../common/consts';
4+
5+
// Before testing begins, allow up to 60 seconds for app to open
6+
describe('Avatar Testing Initialization', function () {
7+
it('Wait for app load', async () => {
8+
await NavigateAppPage.waitForPageDisplayed(BOOT_APP_TIMEOUT);
9+
await expect(await NavigateAppPage.isPageLoaded()).toBeTruthy(NavigateAppPage.ERRORMESSAGE_APPLOAD);
10+
});
11+
12+
it('Click and navigate to Avatar test page', async () => {
13+
await AvatarPageObject.mobileScrollToComponentButton();
14+
await AvatarPageObject.waitForButtonDisplayed(PAGE_TIMEOUT);
15+
16+
/* Click on component button to navigate to test page */
17+
await NavigateAppPage.clickAndGoToAvatarPage();
18+
await AvatarPageObject.waitForPageDisplayed(PAGE_TIMEOUT);
19+
20+
await expect(await AvatarPageObject.isPageLoaded()).toBeTruthy(AvatarPageObject.ERRORMESSAGE_PAGELOAD);
21+
});
22+
});

apps/E2E/src/Button/pages/ButtonPageObject.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ class ButtonPageObject extends BasePage {
6363
get _pageButton() {
6464
return By(HOMEPAGE_BUTTON_BUTTON);
6565
}
66+
67+
get _pageButtonName() {
68+
return HOMEPAGE_BUTTON_BUTTON;
69+
}
6670
}
6771

6872
export default new ButtonPageObject();
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import NavigateAppPage from '../../common/NavigateAppPage';
2+
import ButtonPageObject from '../pages/ButtonPageObject';
3+
import { PAGE_TIMEOUT, BOOT_APP_TIMEOUT } from '../../common/consts';
4+
5+
// Before testing begins, allow up to 60 seconds for app to open
6+
describe('Button Testing Initialization', function () {
7+
it('Wait for app load', async () => {
8+
await NavigateAppPage.waitForPageDisplayed(BOOT_APP_TIMEOUT);
9+
await expect(await NavigateAppPage.isPageLoaded()).toBeTruthy();
10+
});
11+
12+
it('Click and navigate to Button test page', async () => {
13+
await ButtonPageObject.mobileScrollToComponentButton();
14+
await ButtonPageObject.waitForButtonDisplayed(PAGE_TIMEOUT);
15+
16+
/* Click on component button to navigate to test page */
17+
await NavigateAppPage.clickAndGoToButtonPage();
18+
await ButtonPageObject.waitForPageDisplayed(PAGE_TIMEOUT);
19+
20+
await expect(await ButtonPageObject.isPageLoaded()).toBeTruthy();
21+
});
22+
});

apps/E2E/src/CheckboxExperimental/pages/ExperimentalCheckboxPageObject.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ class ExperimentalCheckboxPageObject extends BasePage {
8282
get _pageButton() {
8383
return By(HOMEPAGE_CHECKBOX_EXPERIMENTAL_BUTTON);
8484
}
85+
86+
get _pageButtonName() {
87+
return HOMEPAGE_CHECKBOX_EXPERIMENTAL_BUTTON;
88+
}
8589
}
8690

8791
export default new ExperimentalCheckboxPageObject();
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import NavigateAppPage from '../../common/NavigateAppPage';
2+
import ExperimentalCheckboxPageObject from '../pages/ExperimentalCheckboxPageObject';
3+
import { PAGE_TIMEOUT, BOOT_APP_TIMEOUT } from '../../common/consts';
4+
5+
describe('Experimental Checkbox Testing Initialization', () => {
6+
it('Wait for app load', async () => {
7+
await NavigateAppPage.waitForPageDisplayed(BOOT_APP_TIMEOUT);
8+
await expect(await NavigateAppPage.isPageLoaded()).toBeTruthy(NavigateAppPage.ERRORMESSAGE_APPLOAD);
9+
});
10+
11+
it('Click and navigate to Experimental Checkbox test page', async () => {
12+
await ExperimentalCheckboxPageObject.mobileScrollToComponentButton();
13+
await ExperimentalCheckboxPageObject.waitForButtonDisplayed(PAGE_TIMEOUT);
14+
15+
/* Click on component button to navigate to test page */
16+
await NavigateAppPage.clickAndGoToCheckboxExperimentalPage();
17+
await ExperimentalCheckboxPageObject.waitForPageDisplayed(PAGE_TIMEOUT);
18+
19+
await expect(await ExperimentalCheckboxPageObject.isPageLoaded()).toBeTruthy(ExperimentalCheckboxPageObject.ERRORMESSAGE_PAGELOAD);
20+
});
21+
});

0 commit comments

Comments
 (0)