Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Add Detox e2e tests. #340

Merged
merged 10 commits into from
Jan 3, 2024
90 changes: 69 additions & 21 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ jobs:
runs-on: ubuntu-latest
outputs:
package-common-released: ${{ steps.release.outputs['packages/shared/common--release_created'] }}
package-sdk-client-released: ${{ steps.release.outputs['packages/shared/sdk-client--release_created'] }}
package-sdk-server-released: ${{ steps.release.outputs['packages/shared/sdk-server--release_created'] }}
package-sdk-server-edge-released: ${{ steps.release.outputs['packages/shared/sdk-server-edge--release_created'] }}
package-akamai-edgeworker-sdk-released: ${{ steps.release.outputs['packages/shared/akamai-edgeworker-sdk--release_created'] }}
package-cloudflare-released: ${{ steps.release.outputs['packages/sdk/cloudflare--release_created'] }}
package-react-native-released: ${{ steps.release.outputs['packages/sdk/react-native--release_created'] }}
package-server-node-released: ${{ steps.release.outputs['packages/sdk/server-node--release_created'] }}
package-vercel-released: ${{ steps.release.outputs['packages/sdk/vercel--release_created'] }}
package-akamai-base-released: ${{ steps.release.outputs['packages/sdk/akamai-base--release_created'] }}
Expand Down Expand Up @@ -41,7 +43,7 @@ jobs:
node-version: 16.x
registry-url: 'https://registry.npmjs.org'
- uses: ./actions/install-npm-version
with:
with:
npm_version: 9.5.0
- id: release-common
name: Full release of packages/shared/common
Expand All @@ -50,6 +52,29 @@ jobs:
workspace_path: packages/shared/common
aws_assume_role: ${{ vars.AWS_ROLE_ARN }}

release-sdk-client:
runs-on: ubuntu-latest
needs: ['release-please']
permissions:
id-token: write
contents: write
if: ${{ needs.release-please.outputs.package-sdk-client-released }}
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18.x
registry-url: 'https://registry.npmjs.org'
- uses: ./actions/install-npm-version
with:
npm_version: 10.2.3
- id: release-sdk-client
name: Full release of packages/shared/sdk-client
uses: ./actions/full-release
with:
workspace_path: packages/shared/sdk-client
aws_assume_role: ${{ vars.AWS_ROLE_ARN }}

release-sdk-server:
runs-on: ubuntu-latest
needs: ['release-please']
Expand All @@ -64,9 +89,9 @@ jobs:
node-version: 16.x
registry-url: 'https://registry.npmjs.org'
- uses: ./actions/install-npm-version
with:
with:
npm_version: 9.5.0
- id: release-common
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bug in the existing config. This step id should say release-sdk-server, but it says release-common instead. I think it's an artifact of copy pasting. The other packages suffer from the same bug and I've fixed them all too.

- id: release-sdk-server
name: Full release of packages/shared/sdk-server
uses: ./actions/full-release
with:
Expand All @@ -87,9 +112,9 @@ jobs:
node-version: 16.x
registry-url: 'https://registry.npmjs.org'
- uses: ./actions/install-npm-version
with:
with:
npm_version: 9.5.0
- id: release-common
- id: release-sdk-server-edge
name: Full release of packages/shared/sdk-server-edge
uses: ./actions/full-release
with:
Expand All @@ -110,9 +135,9 @@ jobs:
node-version: 16.x
registry-url: 'https://registry.npmjs.org'
- uses: ./actions/install-npm-version
with:
with:
npm_version: 9.5.0
- id: release-common
- id: release-akamai-edgeworker-sdk
name: Full release of packages/shared/akamai-edgeworker-sdk
uses: ./actions/full-release
with:
Expand All @@ -133,15 +158,38 @@ jobs:
node-version: 16.x
registry-url: 'https://registry.npmjs.org'
- uses: ./actions/install-npm-version
with:
with:
npm_version: 9.5.0
- id: release-common
- id: release-cloudflare
name: Full release of packages/sdk/cloudflare
uses: ./actions/full-release
with:
workspace_path: packages/sdk/cloudflare
aws_assume_role: ${{ vars.AWS_ROLE_ARN }}

release-react-native:
runs-on: ubuntu-latest
needs: ['release-please']
permissions:
id-token: write
contents: write
if: ${{ needs.release-please.outputs.package-react-native-released }}
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18.x
registry-url: 'https://registry.npmjs.org'
- uses: ./actions/install-npm-version
with:
npm_version: 10.2.3
- id: release-react-native
name: Full release of packages/sdk/react-native
uses: ./actions/full-release
with:
workspace_path: packages/sdk/react-native
aws_assume_role: ${{ vars.AWS_ROLE_ARN }}

release-server-node:
runs-on: ubuntu-latest
needs: ['release-please']
Expand All @@ -156,9 +204,9 @@ jobs:
node-version: 16.x
registry-url: 'https://registry.npmjs.org'
- uses: ./actions/install-npm-version
with:
with:
npm_version: 9.5.0
- id: release-common
- id: release-server-node
name: Full release of packages/sdk/server-node
uses: ./actions/full-release
with:
Expand All @@ -179,9 +227,9 @@ jobs:
node-version: 16.x
registry-url: 'https://registry.npmjs.org'
- uses: ./actions/install-npm-version
with:
with:
npm_version: 9.5.0
- id: release-common
- id: release-vercel
name: Full release of packages/sdk/vercel
uses: ./actions/full-release
with:
Expand All @@ -202,9 +250,9 @@ jobs:
node-version: 16.x
registry-url: 'https://registry.npmjs.org'
- uses: ./actions/install-npm-version
with:
with:
npm_version: 9.5.0
- id: release-common
- id: release-akamai-base
name: Full release of packages/sdk/akamai-base
uses: ./actions/full-release
with:
Expand All @@ -225,9 +273,9 @@ jobs:
node-version: 16.x
registry-url: 'https://registry.npmjs.org'
- uses: ./actions/install-npm-version
with:
with:
npm_version: 9.5.0
- id: release-common
- id: release-akamai-edgekv
name: Full release of packages/sdk/akamai-edgekv
uses: ./actions/full-release
with:
Expand All @@ -248,13 +296,13 @@ jobs:
node-version: 16.x
registry-url: 'https://registry.npmjs.org'
- uses: ./actions/install-npm-version
with:
with:
npm_version: 9.5.0
- run: |
sudo apt-get update
sudo apt-get install redis-server
sudo service redis-server start
- id: release-common
- id: release-node-server-sdk-redis
name: Full release of packages/store/node-server-sdk-redis
uses: ./actions/full-release
with:
Expand All @@ -275,11 +323,11 @@ jobs:
node-version: 16.x
registry-url: 'https://registry.npmjs.org'
- uses: ./actions/install-npm-version
with:
with:
npm_version: 9.5.0
- run: |
sudo docker run -d -p 8000:8000 amazon/dynamodb-local
- id: release-common
- id: release-node-server-sdk-dynamodb
name: Full release of packages/store/node-server-sdk-dynamodb
uses: ./actions/full-release
with:
Expand Down
83 changes: 83 additions & 0 deletions packages/sdk/react-native/example/.detoxrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/** @type {Detox.DetoxConfig} */
module.exports = {
testRunner: {
args: {
$0: 'jest',
config: 'e2e/jest.config.js',
},
jest: {
setupTimeout: 120000,
},
},
apps: {
'ios.debug': {
type: 'ios.app',
binaryPath: 'ios/build/Build/Products/Debug-iphonesimulator/reactnativeexample.app',
build:
'xcodebuild -workspace ios/reactnativeexample.xcworkspace -scheme reactnativeexample -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build',
},
'ios.release': {
type: 'ios.app',
binaryPath: 'ios/build/Build/Products/Release-iphonesimulator/reactnativeexample.app',
build:
'xcodebuild -workspace ios/reactnativeexample.xcworkspace -scheme reactnativeexample -configuration Release -sdk iphonesimulator -derivedDataPath ios/build',
},
'android.debug': {
type: 'android.apk',
binaryPath: 'android/app/build/outputs/apk/debug/app-debug.apk',
build: 'cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug',
reversePorts: [8081],
},
'android.release': {
type: 'android.apk',
binaryPath: 'android/app/build/outputs/apk/release/app-release.apk',
build: 'cd android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release',
},
},
devices: {
simulator: {
type: 'ios.simulator',
device: {
type: 'iPhone 15',
},
},
attached: {
type: 'android.attached',
device: {
adbName: '.*',
},
},
emulator: {
type: 'android.emulator',
device: {
avdName: 'Pixel_3a_API_33_arm64-v8a',
},
},
},
configurations: {
'ios.sim.debug': {
device: 'simulator',
app: 'ios.debug',
},
'ios.sim.release': {
device: 'simulator',
app: 'ios.release',
},
'android.att.debug': {
device: 'attached',
app: 'android.debug',
},
'android.att.release': {
device: 'attached',
app: 'android.release',
},
'android.emu.debug': {
device: 'emulator',
app: 'android.debug',
},
'android.emu.release': {
device: 'emulator',
app: 'android.release',
},
},
};
36 changes: 34 additions & 2 deletions packages/sdk/react-native/example/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## LaunchDarkly React Native SDK example app
# LaunchDarkly React Native SDK example app

To run the example app:
## Quickstart

1. At the js-core repo root:

Expand Down Expand Up @@ -28,3 +28,35 @@ yarn && yarn ios-go
# android
yarn && yarn android-release
```

## Running Detox e2e tests

1. Install the required tools on OS X:

```shell
npm install detox-cli --global
brew tap wix/brew
brew install applesimutils
```

2. Detox uses the example app to run tests. The example app needs a mobile key set in an `.env` file
at the same level as this README. Ensure this file exists and add your mobile key to that `.env` file:

```shell
MOBILE_KEY=abcdef12456
```

3. For the above mobile key, ensure two boolean flags exist `my-boolean-flag-1`
and `my-boolean-flag-2` and they evaluate to true for `test-user`. Make sure these flags have client-side SDK availability checked for mobile sdks.

4. In the example folder, on a terminal:

```shell
yarn && yarn expo-prebuild && yarn start
```

5. Still in the example folder but on another terminal:

```shell
yarn detox-ios
```
13 changes: 13 additions & 0 deletions packages/sdk/react-native/example/e2e/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/** @type {import('@jest/types').Config.InitialOptions} */
module.exports = {
preset: 'react-native',
rootDir: '..',
testMatch: ['<rootDir>/e2e/**/*.test.ts'],
testTimeout: 120000,
maxWorkers: 1,
globalSetup: 'detox/runners/jest/globalSetup',
globalTeardown: 'detox/runners/jest/globalTeardown',
reporters: ['detox/runners/jest/reporter'],
testEnvironment: 'detox/runners/jest/testEnvironment',
verbose: true,
};
40 changes: 40 additions & 0 deletions packages/sdk/react-native/example/e2e/starter.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { by, device, element, expect, waitFor } from 'detox';

describe('Example', () => {
beforeAll(async () => {
await device.launchApp({
newInstance: true,
launchArgs: {
detoxURLBlacklistRegex: '\\("^https://clientstream.launchdarkly.com/meval"\\)',
},
});
});

// For speed, all tests are sequential and dependent.
// beforeEach(async () => {
// await device.reloadReactNative();
// });

test('app loads and renders correctly', async () => {
await expect(element(by.text(/welcome to launchdarkly/i))).toBeVisible();
await expect(element(by.text(/my-boolean-flag-1: false/i))).toBeVisible();
});

test('identify', async () => {
await element(by.id('userKey')).typeText('test-user');
await element(by.text(/identify/i)).tap();

await waitFor(element(by.text(/my-boolean-flag-1: true/i)))
.toBeVisible()
.withTimeout(2000);
});

test('variation', async () => {
await element(by.id('flagKey')).replaceText('my-boolean-flag-2');
await element(by.text(/get flag value/i)).tap();

await waitFor(element(by.text(/my-boolean-flag-2: true/i)))
.toBeVisible()
.withTimeout(2000);
});
});
Loading