diff --git a/.github/workflows/react-native-code-push-ci.yml b/.github/workflows/react-native-code-push-ci.yml new file mode 100644 index 000000000..e167f8cc0 --- /dev/null +++ b/.github/workflows/react-native-code-push-ci.yml @@ -0,0 +1,48 @@ +name: React-native-code-push CI + +on: + pull_request: + branches: + - master + +jobs: + test-android: + name: Test Android app + runs-on: macos-latest + strategy: + matrix: + api-level: [27] + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Start adb server + run: adb devices + - name: Download system image "android-${{ matrix.api-level }}" + run: $ANDROID_HOME/tools/bin/sdkmanager "system-images;android-${{ matrix.api-level }};google_apis;x86" + - name: Create android emulator + run: $ANDROID_HOME/tools/bin/avdmanager create avd --force --name TestEmulator --abi google_apis/x86 --package 'system-images;android-${{ matrix.api-level }};google_apis;x86' --device "Nexus 6P" + - name: Start android emulator + run: $ANDROID_HOME/emulator/emulator -avd TestEmulator -noaudio -no-window -no-snapshot-save -no-boot-anim -memory 6144 & + - run: sleep 120 + - run: adb shell settings put global window_animation_scale 0.0 + - run: adb shell settings put global transition_animation_scale 0.0 + - run: adb shell settings put global animator_duration_scale 0.0 + - name: Package Installation + run: npm install + - name: Install react-native-cli + run: npm install react-native-cli + - name: test:android + run: npm run test:android + + test-iOS: + name: Test iOS app + runs-on: macos-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Install dependecies + run: npm install + - name: Install react-native-cli + run: npm install react-native-cli + - name: Run tests + run: npm run test:ios diff --git a/code-push-plugin-testing-framework/script/platform.js b/code-push-plugin-testing-framework/script/platform.js index 3cced7876..5c241f3e0 100644 --- a/code-push-plugin-testing-framework/script/platform.js +++ b/code-push-plugin-testing-framework/script/platform.js @@ -231,7 +231,7 @@ var AndroidEmulatorManager = (function () { * Ends a running application given its app id. */ AndroidEmulatorManager.prototype.endRunningApplication = function (appId) { - return testUtil_1.TestUtil.getProcessOutput("adb shell am force-stop " + appId).then(function () { return null; }); + return testUtil_1.TestUtil.getProcessOutput("adb shell am force-stop " + appId).then(function () { return Q.delay(10000); }); }; /** * Restarts an already installed application by app id. @@ -240,8 +240,8 @@ var AndroidEmulatorManager = (function () { var _this = this; return this.endRunningApplication(appId) .then(function () { - // Wait for a second before restarting. - return Q.delay(1000); + // Wait for a 10 seconds before restarting. + return Q.delay(10000); }) .then(function () { return _this.launchInstalledApplication(appId); diff --git a/code-push-plugin-testing-framework/script/serverUtil.js b/code-push-plugin-testing-framework/script/serverUtil.js index cc4ed6d3f..80503628d 100644 --- a/code-push-plugin-testing-framework/script/serverUtil.js +++ b/code-push-plugin-testing-framework/script/serverUtil.js @@ -129,18 +129,25 @@ exports.createUpdateResponse = createUpdateResponse; function expectTestMessages(expectedMessages) { var deferred = Q.defer(); var messageIndex = 0; + var lastRequestBody = null; exports.testMessageCallback = function (requestBody) { try { console.log("Message index: " + messageIndex); - if (typeof expectedMessages[messageIndex] === "string") { - assert.equal(requestBody.message, expectedMessages[messageIndex]); - } - else { - assert(areEqual(requestBody, expectedMessages[messageIndex])); - } - /* end of message array */ - if (++messageIndex === expectedMessages.length) { - deferred.resolve(undefined); + // We should ignore duplicated requests. It is only CI issue. + if (lastRequestBody === null || !areEqual(requestBody, lastRequestBody)) { + if (typeof expectedMessages[messageIndex] === "string") { + assert.equal(requestBody.message, expectedMessages[messageIndex]); + } + else { + assert(areEqual(requestBody, expectedMessages[messageIndex])); + } + + lastRequestBody = requestBody; + + /* end of message array */ + if (++messageIndex === expectedMessages.length) { + deferred.resolve(undefined); + } } } catch (e) { diff --git a/test/test.ts b/test/test.ts index c80dcf860..e89230a4b 100644 --- a/test/test.ts +++ b/test/test.ts @@ -112,19 +112,30 @@ class RNAndroid extends Platform.Android implements RNPlatform { return TestUtil.getProcessOutput("adb install -r " + this.getBinaryPath(projectDirectory), { cwd: androidDirectory }).then(() => { return null; }); } + /** + * Build function of the test application, the command depends on the OS + */ + buildFunction(androidDirectory: string): Q.Promise { + if (process.platform === "darwin") { + return TestUtil.getProcessOutput(`./gradlew assembleRelease --daemon`, { noLogStdOut: true, cwd: androidDirectory }) + .then(() => { return null; }); + } else { + return TestUtil.getProcessOutput(`gradlew assembleRelease --daemon`, { noLogStdOut: true, cwd: androidDirectory }) + .then(() => { return null; }); + } + } + /** * Builds the binary of the project on this platform. */ buildApp(projectDirectory: string): Q.Promise { // In order to run on Android without the package manager, we must create a release APK and then sign it with the debug certificate. const androidDirectory: string = path.join(projectDirectory, TestConfig.TestAppName, "android"); - const apkPath = this.getBinaryPath(projectDirectory); - if (process.platform === "darwin") { - return TestUtil.getProcessOutput(`./gradlew assembleRelease --daemon`, { cwd: androidDirectory }) - .then(() => { return null; }); - } else { - return TestUtil.getProcessOutput(`gradlew assembleRelease --daemon`, { cwd: androidDirectory }) - .then(() => { return null; }); + // If the build fails for the first time, try rebuild app again + try { + return this.buildFunction(androidDirectory); + } catch { + return this.buildFunction(androidDirectory); } } }