├── .bundle
└── config
├── .eslintrc.js
├── .github
├── ISSUE_TEMPLATE
│ ├── --bug-report.md
│ ├── --documentation.md
│ ├── --feature-request.md
│ └── --question.md
├── scripts
│ ├── create_release.sh
│ └── upload_artifacts.sh
├── stale.yml
└── workflows
│ ├── expense.yml
│ └── publish.apps.yml
├── .gitignore
├── .prettierrc.js
├── .vscode
└── settings.json
├── .watchmanconfig
├── Gemfile
├── Gemfile.lock
├── LICENSE-MIT
├── README.md
├── __tests__
└── App.test.tsx
├── android
├── app
│ ├── build.gradle
│ ├── debug.keystore
│ ├── proguard-rules.pro
│ ├── src
│ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── wdiodemoapp
│ │ │ │ ├── MainActivity.kt
│ │ │ │ └── MainApplication.kt
│ │ │ └── res
│ │ │ ├── drawable-hdpi
│ │ │ └── bootsplash_logo.png
│ │ │ ├── drawable-mdpi
│ │ │ └── bootsplash_logo.png
│ │ │ ├── drawable-xhdpi
│ │ │ └── bootsplash_logo.png
│ │ │ ├── drawable-xxhdpi
│ │ │ └── bootsplash_logo.png
│ │ │ ├── drawable-xxxhdpi
│ │ │ └── bootsplash_logo.png
│ │ │ ├── drawable
│ │ │ └── rn_edit_text_material.xml
│ │ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ └── values
│ │ │ ├── colors.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ └── wdio-native-app-upload-key.keystore
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
├── babel.config.js
├── docs
├── CONTRIBUTING.md
└── VERSIONING.md
├── index.js
├── ios
├── .xcode.env
├── Podfile
├── Podfile.lock
├── wdiodemoapp.xcodeproj
│ ├── project.pbxproj
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── wdiodemoapp.xcscheme
├── wdiodemoapp.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── wdiodemoapp
│ ├── AppDelegate.h
│ ├── AppDelegate.mm
│ ├── BootSplash.storyboard
│ ├── Images.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── 1024.png
│ │ │ ├── 114.png
│ │ │ ├── 120.png
│ │ │ ├── 180.png
│ │ │ ├── 29.png
│ │ │ ├── 40.png
│ │ │ ├── 57.png
│ │ │ ├── 58.png
│ │ │ ├── 60.png
│ │ │ ├── 80.png
│ │ │ ├── 87.png
│ │ │ └── Contents.json
│ │ ├── AppIcon1.appiconset
│ │ │ └── Contents.json
│ │ ├── BootSplashLogo.imageset
│ │ │ ├── Contents.json
│ │ │ ├── bootsplash_logo.png
│ │ │ ├── bootsplash_logo@2x.png
│ │ │ └── bootsplash_logo@3x.png
│ │ ├── Contents.json
│ │ └── webdriverio.imageset
│ │ │ ├── Contents.json
│ │ │ ├── webdriverio.png
│ │ │ ├── webdriverio@2x.png
│ │ │ └── webdriverio@3x.png
│ ├── Info.plist
│ ├── LaunchScreen.storyboard
│ └── main.m
└── wdiodemoappTests
│ ├── Info.plist
│ └── wdiodemoappTests.m
├── jest.config.js
├── metro.config.js
├── package-lock.json
├── package.json
├── patches
└── react-native+0.73.1.patch
├── react-native.config.js
├── src
├── App.tsx
├── app.json
├── assets
│ ├── images
│ │ ├── wdio-c1.png
│ │ ├── wdio-c2.png
│ │ ├── wdio-c3.png
│ │ ├── wdio-l1.png
│ │ ├── wdio-l2.png
│ │ ├── wdio-l3.png
│ │ ├── wdio-r1.png
│ │ ├── wdio-r2.png
│ │ └── wdio-r3.png
│ ├── io.png
│ └── webdriverio.png
├── components
│ ├── BorderText.tsx
│ ├── Button.tsx
│ ├── Draggable.tsx
│ ├── FormComponents.tsx
│ ├── LoginForm.tsx
│ ├── SliderEntry.tsx
│ ├── StatusBar.tsx
│ └── TitleDivider.tsx
├── config
│ ├── Colors.js
│ ├── Constants.ts
│ └── TestProperties.ts
└── screens
│ ├── Drag.tsx
│ ├── Forms.tsx
│ ├── Home.tsx
│ ├── Login.tsx
│ ├── Swipe.tsx
│ └── WebView.tsx
└── tsconfig.json
/.bundle/config:
--------------------------------------------------------------------------------
1 | BUNDLE_PATH: "vendor/bundle"
2 | BUNDLE_FORCE_RUBY_PLATFORM: 1
3 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | extends: '@react-native',
4 | };
5 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/--bug-report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "\U0001F41BBug report"
3 | about: Create a report to help us improve.
4 |
5 | ---
6 |
7 | **Environment (please complete the following information):**
8 | - Node.js version: [e.g. 8.9.1]
9 | - NPM version: [e.g. 5.8.0]
10 | - Platform: [e.g. Android]
11 | - Platform version: [e.g. 8.1.0]
12 | - Emulator/Simulator/Real Device: [e.g. Emulator]
13 |
14 | **Describe the bug**
15 | A clear and concise description of what the bug is.
16 |
17 | **To Reproduce**
18 | Steps to reproduce the behavior
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Additional context**
27 | Add any other context about the problem here.
28 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/--documentation.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "\U0001F4D6Documentation"
3 | about: Suggest improvements or report missing/unclear documentation.
4 |
5 | ---
6 |
7 | **Pre-check**
8 | - [ ] I'm aware that I can [edit the docs](https://github.com/webdriverio/native-demo-app) and submit a pull request
9 |
10 | **Describe the improvement**
11 |
12 | I'd like to report
13 | - [ ] Unclear documentation
14 | - [ ] A typo
15 | - [ ] Missing documentation
16 | - [ ] Other
17 |
18 | **Description of the improvement / report**
19 | A clear and concise description.
20 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/--feature-request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "\U0001F4A1Feature request"
3 | about: Suggest an idea for this module.
4 |
5 | ---
6 |
7 | **Is your feature request related to a problem? Please describe.**
8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
9 |
10 | **Describe the solution you'd like**
11 | A clear and concise description of what you want to happen.
12 |
13 | **Describe alternatives you've considered**
14 | A clear and concise description of any alternative solutions or features you've considered.
15 |
16 | **Additional context**
17 | Add any other context or screenshots about the feature request here.
18 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/--question.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "\U0001F4ACQuestion"
3 | about: Ask questions.
4 |
5 | ---
6 |
7 | **Describe your question with as much detail as possible**
8 | A clear and concise question that doesn't require too much conversation. Need more help? [Find us on Discord](https://discord.webdriver.io)
9 |
10 |
11 | **If it's about a specific piece of code, try and include some of it to support your question.**
12 | [...]
13 |
14 |
15 | **Environment (please complete the following information):**
16 | - Node.js version: [e.g. 8.9.1]
17 | - NPM version: [e.g. 5.8.0]
18 | - Platform: [e.g. Android]
19 | - Platform version: [e.g. 8.1.0]
20 | - Emulator/Simulator/Real Device: [e.g. Emulator]
21 |
22 |
23 | **Additional context**
24 | Add any other context about the problem here.
25 |
--------------------------------------------------------------------------------
/.github/scripts/create_release.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Variables passed as environment
4 | TOKEN=$GITHUB_TOKEN
5 | TAG_NAME=$TAG_NAME
6 | RELEASE_NAME=$RELEASE_NAME
7 | BODY=$BODY
8 | DRAFT=$DRAFT
9 | PRE_RELEASE=$PRE_RELEASE
10 |
11 | # Repository info
12 | REPO_OWNER=$(jq -r ".repository.owner.login" $GITHUB_EVENT_PATH)
13 | REPO_NAME=$(jq -r ".repository.name" $GITHUB_EVENT_PATH)
14 |
15 | # GitHub API URL for creating a release
16 | API_URL="https://api.github.com/repos/$REPO_OWNER/$REPO_NAME/releases"
17 |
18 | # Data for the release
19 | DATA=$(jq -n --arg tag_name "$TAG_NAME" \
20 | --arg name "$RELEASE_NAME" \
21 | --arg body "$BODY" \
22 | --argjson draft $(echo $DRAFT | tr '[:upper:]' '[:lower:]') \
23 | --argjson prerelease $(echo $PRE_RELEASE | tr '[:upper:]' '[:lower:]') \
24 | '{tag_name: $tag_name, name: $name, body: $body, draft: $draft, prerelease: $prerelease}')
25 |
26 | # Make a POST request to create the release
27 | RESPONSE=$(curl -H "Authorization: token $TOKEN" \
28 | -H "Content-Type: application/json" \
29 | --data "$DATA" \
30 | $API_URL)
31 |
32 | # Check if the release was successfully created
33 | RELEASE_ID=$(echo $RESPONSE | jq -r ".id")
34 |
35 | if [ "$RELEASE_ID" != "null" ]; then
36 | echo "Release created successfully! ID: $RELEASE_ID"
37 | ASSET_URL=$(echo $RESPONSE | jq -r ".upload_url")
38 | ASSET_URL="${ASSET_URL%\{*}"
39 | echo "ASSET_URL=$ASSET_URL" >> $GITHUB_ENV
40 | else
41 | echo "Failed to create release"
42 | echo "Response:"
43 | echo $RESPONSE
44 | exit 1
45 | fi
46 |
--------------------------------------------------------------------------------
/.github/scripts/upload_artifacts.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Variables passed from the workflow
4 | ASSET_URL=$1
5 | NEW_VERSION=$2
6 | GITHUB_TOKEN=$3
7 |
8 | # Trim off the end of the URL
9 | ASSET_URL="${ASSET_URL%\{*}"
10 |
11 | echo "Uploading Android App..."
12 | curl \
13 | -X POST \
14 | -H "Authorization: token $GITHUB_TOKEN" \
15 | -H "Content-Type: $(file -b --mime-type ./android.wdio.native.app.$NEW_VERSION.apk)" \
16 | --data-binary @./android.wdio.native.app.$NEW_VERSION.apk \
17 | "$ASSET_URL?name=android.wdio.native.app.$NEW_VERSION.apk"
18 |
19 | echo "Uploading iOS App..."
20 | curl \
21 | -X POST \
22 | -H "Authorization: token $GITHUB_TOKEN" \
23 | -H "Content-Type: $(file -b --mime-type ./ios.simulator.wdio.native.app.$NEW_VERSION.zip)" \
24 | --data-binary @./ios.simulator.wdio.native.app.$NEW_VERSION.zip \
25 | "$ASSET_URL?name=ios.simulator.wdio.native.app.$NEW_VERSION.zip"
26 |
--------------------------------------------------------------------------------
/.github/stale.yml:
--------------------------------------------------------------------------------
1 | # Number of days of inactivity before an issue becomes stale
2 | daysUntilStale: 60
3 | # Number of days of inactivity before a stale issue is closed
4 | daysUntilClose: 14
5 | # Issues with these labels will never be considered stale
6 | exemptLabels:
7 | - bug
8 | # Label to use when marking an issue as stale
9 | staleLabel: wontfix
10 | # Comment to post when marking an issue as stale. Set to `false` to disable
11 | markComment: >
12 | This issue has been automatically marked as stale because it has not had
13 | recent activity. It will be closed if no further activity occurs. Thank you
14 | for your contributions.
15 | # Comment to post when closing a stale issue. Set to `false` to disable
16 | closeComment: false
17 |
--------------------------------------------------------------------------------
/.github/workflows/expense.yml:
--------------------------------------------------------------------------------
1 | name: Expense Contribution
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | prNumber:
7 | description: "Number of the PR (without #)"
8 | required: true
9 | amount:
10 | description: "The expense amount you like to grant for the contribution in $"
11 | required: true
12 | type: choice
13 | options:
14 | - 15
15 | - 25
16 | - 35
17 | - 50
18 | - 100
19 | - 150
20 | - 200
21 | - 250
22 | - 300
23 | - 350
24 | - 400
25 | - 450
26 | - 500
27 | - 550
28 | - 600
29 | - 650
30 | - 700
31 | - 750
32 | - 800
33 | - 850
34 | - 900
35 | - 950
36 | - 1000
37 |
38 | jobs:
39 | authorize:
40 | runs-on: ubuntu-latest
41 | steps:
42 | - uses: octokit/request-action@v2.1.9
43 | with:
44 | route: GET /orgs/:organisation/teams/:team/memberships/${{ github.actor }}
45 | team: technical-steering-committee
46 | organisation: webdriverio
47 | env:
48 | GITHUB_TOKEN: ${{ secrets.WDIO_BOT_GITHUB_TOKEN }}
49 | expense:
50 | permissions:
51 | contents: write
52 | id-token: write
53 | needs: [authorize]
54 | runs-on: ubuntu-latest
55 | steps:
56 | - name: Run Expense Flow
57 | uses: webdriverio/expense-action@v1
58 | with:
59 | prNumber: ${{ github.event.inputs.prNumber }}
60 | amount: ${{ github.event.inputs.amount }}
61 | env:
62 | RESEND_API_KEY: ${{ secrets.RESEND_API_KEY }}
63 | GH_TOKEN: ${{ secrets.WDIO_BOT_GITHUB_TOKEN }}
64 |
--------------------------------------------------------------------------------
/.github/workflows/publish.apps.yml:
--------------------------------------------------------------------------------
1 | name: Build and Publish WebdriverIO Native Demo Apps
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | releaseType:
7 | description: 'Release type - major, minor or patch'
8 | required: true
9 | default: 'patch'
10 |
11 | concurrency:
12 | group: ${{ github.workflow }}-${{ github.ref }}
13 | cancel-in-progress: true
14 |
15 | jobs:
16 | prepare_release:
17 | runs-on: macos-latest
18 | outputs:
19 | new_version: ${{ steps.set_new_version.outputs.new_version }}
20 | steps:
21 | - name: ⬇️ Checkout Repository
22 | uses: actions/checkout@v3
23 |
24 | - name: 🌲 Setup Git
25 | run: |
26 | git config --global user.email "bot@webdriver.io"
27 | git config --global user.name "WebdriverIO Release Bot"
28 |
29 | - name: 🌲 Setup Node.js
30 | uses: actions/setup-node@v3
31 | with:
32 | node-version: '20.x'
33 |
34 | - name: 🧩 Install Dependencies
35 | run: npm ci
36 |
37 | - name: 🔄 Increment Version and Build Number
38 | id: set_new_version
39 | run: |
40 | NEW_VERSION=$(npm version ${{ github.event.inputs.releaseType }} --no-git-tag-version)
41 | echo "new_version=$NEW_VERSION" >> $GITHUB_ENV
42 | echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
43 | echo "New version: $NEW_VERSION"
44 | npm run build.versions
45 |
46 | - name: 🌿 Create Pre-Release Branch
47 | run: |
48 | git checkout -b pre-release
49 | git add .
50 | git commit -m "chore: Preparing for release $NEW_VERSION"
51 | git push origin pre-release
52 |
53 | android_build:
54 | needs: prepare_release
55 | runs-on: ubuntu-latest
56 | steps:
57 | - name: ⬇️ Checkout Pre-Release Branch
58 | uses: actions/checkout@v3
59 | with:
60 | ref: pre-release
61 |
62 | - name: 🧳 Cache Gradle Wrapper
63 | uses: actions/cache@v3
64 | with:
65 | path: |
66 | ~/.gradle/wrapper
67 | key: ${{ runner.os }}-gradle-wrapper-${{ hashFiles('**/gradle-wrapper.properties') }}
68 |
69 | - name: 🧳 Cache Gradle Dependencies
70 | uses: actions/cache@v3
71 | with:
72 | path: |
73 | ~/.gradle/caches
74 | key: ${{ runner.os }}-gradle-cache-${{ hashFiles('**/*.gradle*', '**/gradle.lockfile') }}
75 | restore-keys: |
76 | ${{ runner.os }}-gradle-cache-
77 |
78 | - name: ☕ Setup Java and Android SDK
79 | uses: actions/setup-java@v4
80 | with:
81 | distribution: 'zulu'
82 | java-version: '17.x'
83 |
84 | - name: 🌲 Setup Node.js
85 | uses: actions/setup-node@v3
86 | with:
87 | node-version: '20.x'
88 |
89 | - name: 🧩 Install Dependencies
90 | run: npm ci
91 |
92 | - name: 🏗️ Build Android Release
93 | run: npm run android.release
94 |
95 | - name: 📦 Move 🤖 Android Build
96 | run: mv android/app/build/outputs/apk/release/app-release.apk android.wdio.native.app.${{ needs.prepare_release.outputs.new_version }}.apk
97 |
98 | - name: 📤 Upload Android App
99 | uses: actions/upload-artifact@v3
100 | with:
101 | name: android.wdio.native.app.${{ needs.prepare_release.outputs.new_version }}.apk
102 | path: android.wdio.native.app.${{ needs.prepare_release.outputs.new_version }}.apk
103 |
104 | ios_build:
105 | needs: prepare_release
106 | # for https://github.com/facebook/react-native/issues/38294
107 | runs-on: macos-13
108 | steps:
109 | - name: ⬇️ Checkout Pre-Release Branch
110 | uses: actions/checkout@v3
111 | with:
112 | ref: pre-release
113 |
114 | - name: 🧳 Cache Cocoapods Pods
115 | uses: actions/cache@v3
116 | with:
117 | path: ios/Pods
118 | key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }}-20231231
119 | restore-keys: |
120 | ${{ runner.os }}-pods-
121 |
122 | - name: 🌲 Setup Node.js
123 | uses: actions/setup-node@v3
124 | with:
125 | node-version: '20.x'
126 |
127 | - name: 🧩 Install Dependencies
128 | run: npm ci
129 |
130 | # This is temp to fix the issue
131 | # "error Cannot start server in new window because no terminal app was specified."
132 | - name: 🚇 Start Metro Bundler
133 | run: npm start -- --reset-cache &
134 |
135 | # Using the 'verbose' xcodebuild command instead of the RN command
136 | # to be able to alter the build path
137 | - name: 🏗️ Build iOS Release
138 | run: |
139 | cd ios
140 | pod install
141 | xcodebuild \
142 | -workspace wdiodemoapp.xcworkspace \
143 | -configuration Release \
144 | -scheme wdiodemoapp \
145 | -sdk iphonesimulator \
146 | -derivedDataPath ./build \
147 | CODE_SIGN_IDENTITY="" \
148 | CODE_SIGNING_REQUIRED=NO
149 | CODE_SIGNING_ALLOWED=NO
150 |
151 | - name: 🛑 Stop Metro Bundler
152 | if: always()
153 | run: kill $(jobs -p) || true
154 |
155 | - name: 📦 Zip and move iOS Simulator Build
156 | run: |
157 | mkdir Payload
158 | cp -R ios/build/Build/Products/Release-iphonesimulator/wdiodemoapp.app Payload
159 | zip -9 -r ios.simulator.wdio.native.app.${{ needs.prepare_release.outputs.new_version }}.zip Payload
160 | rm -rf Payload
161 |
162 | - name: 📤 Upload iOS App
163 | uses: actions/upload-artifact@v3
164 | with:
165 | name: ios.simulator.wdio.native.app.${{ needs.prepare_release.outputs.new_version }}.zip
166 | path: ios.simulator.wdio.native.app.${{ needs.prepare_release.outputs.new_version }}.zip
167 |
168 | finalize:
169 | needs: [prepare_release, android_build, ios_build]
170 | runs-on: ubuntu-latest
171 | if: success()
172 | steps:
173 | - name: ⬇️ Checkout Pre-Release Branch
174 | uses: actions/checkout@v3
175 | with:
176 | ref: pre-release
177 | fetch-depth: 0
178 |
179 | - name: 🌲 Setup Git
180 | run: |
181 | git config --global user.email "bot@webdriver.io"
182 | git config --global user.name "WebdriverIO Release Bot"
183 |
184 | - name: 🔖 Tag New Release
185 | run: |
186 | git tag -a "${{ needs.prepare_release.outputs.new_version }}" -m "Release ${{ needs.prepare_release.outputs.new_version }}"
187 | git push origin "${{ needs.prepare_release.outputs.new_version }}"
188 |
189 | - name: 🔀 Merge Pre-Release to Main
190 | run: |
191 | git fetch
192 | git checkout main
193 | git merge --no-ff pre-release -m "Merging pre-release to main: Release ${{ needs.prepare_release.outputs.new_version }}" || echo "Merge failed, printing diffs next."
194 | git push origin main
195 | continue-on-error: true
196 |
197 | - name: 🕵️ Print Diffs if Merge Fails
198 | if: failure()
199 | run: |
200 | echo "Printing diffs between main and pre-release..."
201 | git diff main pre-release
202 | echo "DIFFS_PRINTED=true" >> $GITHUB_ENV
203 |
204 | - name: 🔥 Delete Pre-Release Branch
205 | run: |
206 | git push origin --delete pre-release
207 | env:
208 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
209 |
210 | - name: 🚀 Create GitHub Release
211 | id: create_release
212 | if: env.DIFFS_PRINTED != 'true'
213 | env:
214 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
215 | TAG_NAME: ${{ needs.prepare_release.outputs.new_version }}
216 | RELEASE_NAME: "Release ${{ needs.prepare_release.outputs.new_version }}"
217 | DRAFT: true
218 | PRE_RELEASE: false
219 | run: |
220 | chmod +x .github/scripts/create_release.sh
221 | .github/scripts/create_release.sh
222 |
223 | - name: 📥 Download Android App Artifact
224 | uses: actions/download-artifact@v3
225 | with:
226 | name: android.wdio.native.app.${{ needs.prepare_release.outputs.new_version }}.apk
227 |
228 | - name: 📥 Download iOS App Artifact
229 | uses: actions/download-artifact@v3
230 | with:
231 | name: ios.simulator.wdio.native.app.${{ needs.prepare_release.outputs.new_version }}.zip
232 |
233 | - name: 📤 Upload Artifacts to Release
234 | if: env.DIFFS_PRINTED != 'true'
235 | env:
236 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
237 | run: |
238 | chmod +x .github/scripts/upload_artifacts.sh
239 | .github/scripts/upload_artifacts.sh "${{ env.ASSET_URL }}" ${{ needs.prepare_release.outputs.new_version }} ${{ secrets.GITHUB_TOKEN }}
240 |
241 | cleanup:
242 | runs-on: ubuntu-latest
243 | if: ${{ failure() && (needs.prepare_release.result == 'failure' || needs.android_build.result == 'failure' || needs.ios_build.result == 'failure' || needs.finalize.result == 'failure') }}
244 | needs: [prepare_release, android_build, ios_build, finalize]
245 | steps:
246 | - name: Checkout Repository
247 | uses: actions/checkout@v3
248 |
249 | - name: 🔥 Delete Pre-Release Branch
250 | run: |
251 | git push origin --delete pre-release
252 | env:
253 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
254 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | ios/.xcode.env.local
24 |
25 | # Android/IntelliJ
26 | #
27 | build/
28 | .idea
29 | .gradle
30 | local.properties
31 | *.iml
32 | *.hprof
33 | .cxx/
34 | *.keystore
35 | !debug.keystore
36 | !wdio-native-app-upload-key.keystore
37 |
38 | # node.js
39 | #
40 | node_modules/
41 | npm-debug.log
42 | yarn-error.log
43 |
44 | # fastlane
45 | #
46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
47 | # screenshots whenever they are needed.
48 | # For more information about the recommended setup visit:
49 | # https://docs.fastlane.tools/best-practices/source-control/
50 |
51 | **/fastlane/report.xml
52 | **/fastlane/Preview.html
53 | **/fastlane/screenshots
54 | **/fastlane/test_output
55 |
56 | # Bundle artifact
57 | *.jsbundle
58 |
59 | # Ruby / CocoaPods
60 | /ios/Pods/
61 | /vendor/bundle/
62 |
63 | # Temporary files created by Metro to check the health of the file watcher
64 | .metro-health-check*
65 |
66 | # testing
67 | /coverage
68 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | arrowParens: 'avoid',
3 | bracketSameLine: true,
4 | bracketSpacing: false,
5 | singleQuote: true,
6 | trailingComma: 'all',
7 | };
8 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "java.configuration.updateBuildConfiguration": "interactive"
3 | }
--------------------------------------------------------------------------------
/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
4 | ruby ">= 2.6.10"
5 |
6 | gem 'cocoapods', '~> 1.13'
7 | gem 'activesupport', '>= 6.1.7.3', '< 7.1.0'
8 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | CFPropertyList (3.0.6)
5 | rexml
6 | activesupport (6.1.7.6)
7 | concurrent-ruby (~> 1.0, >= 1.0.2)
8 | i18n (>= 1.6, < 2)
9 | minitest (>= 5.1)
10 | tzinfo (~> 2.0)
11 | zeitwerk (~> 2.3)
12 | addressable (2.8.6)
13 | public_suffix (>= 2.0.2, < 6.0)
14 | algoliasearch (1.27.5)
15 | httpclient (~> 2.8, >= 2.8.3)
16 | json (>= 1.5.1)
17 | atomos (0.1.3)
18 | claide (1.1.0)
19 | cocoapods (1.14.3)
20 | addressable (~> 2.8)
21 | claide (>= 1.0.2, < 2.0)
22 | cocoapods-core (= 1.14.3)
23 | cocoapods-deintegrate (>= 1.0.3, < 2.0)
24 | cocoapods-downloader (>= 2.1, < 3.0)
25 | cocoapods-plugins (>= 1.0.0, < 2.0)
26 | cocoapods-search (>= 1.0.0, < 2.0)
27 | cocoapods-trunk (>= 1.6.0, < 2.0)
28 | cocoapods-try (>= 1.1.0, < 2.0)
29 | colored2 (~> 3.1)
30 | escape (~> 0.0.4)
31 | fourflusher (>= 2.3.0, < 3.0)
32 | gh_inspector (~> 1.0)
33 | molinillo (~> 0.8.0)
34 | nap (~> 1.0)
35 | ruby-macho (>= 2.3.0, < 3.0)
36 | xcodeproj (>= 1.23.0, < 2.0)
37 | cocoapods-core (1.14.3)
38 | activesupport (>= 5.0, < 8)
39 | addressable (~> 2.8)
40 | algoliasearch (~> 1.0)
41 | concurrent-ruby (~> 1.1)
42 | fuzzy_match (~> 2.0.4)
43 | nap (~> 1.0)
44 | netrc (~> 0.11)
45 | public_suffix (~> 4.0)
46 | typhoeus (~> 1.0)
47 | cocoapods-deintegrate (1.0.5)
48 | cocoapods-downloader (2.1)
49 | cocoapods-plugins (1.0.0)
50 | nap
51 | cocoapods-search (1.0.1)
52 | cocoapods-trunk (1.6.0)
53 | nap (>= 0.8, < 2.0)
54 | netrc (~> 0.11)
55 | cocoapods-try (1.2.0)
56 | colored2 (3.1.2)
57 | concurrent-ruby (1.2.2)
58 | escape (0.0.4)
59 | ethon (0.16.0)
60 | ffi (>= 1.15.0)
61 | ffi (1.16.3)
62 | fourflusher (2.3.1)
63 | fuzzy_match (2.0.4)
64 | gh_inspector (1.1.3)
65 | httpclient (2.8.3)
66 | i18n (1.14.1)
67 | concurrent-ruby (~> 1.0)
68 | json (2.7.1)
69 | minitest (5.20.0)
70 | molinillo (0.8.0)
71 | nanaimo (0.3.0)
72 | nap (1.1.0)
73 | netrc (0.11.0)
74 | public_suffix (4.0.7)
75 | rexml (3.2.6)
76 | ruby-macho (2.5.1)
77 | typhoeus (1.4.1)
78 | ethon (>= 0.9.0)
79 | tzinfo (2.0.6)
80 | concurrent-ruby (~> 1.0)
81 | xcodeproj (1.23.0)
82 | CFPropertyList (>= 2.3.3, < 4.0)
83 | atomos (~> 0.1.3)
84 | claide (>= 1.0.2, < 2.0)
85 | colored2 (~> 3.1)
86 | nanaimo (~> 0.3.0)
87 | rexml (~> 3.2.4)
88 | zeitwerk (2.6.12)
89 |
90 | PLATFORMS
91 | ruby
92 |
93 | DEPENDENCIES
94 | activesupport (>= 6.1.7.3, < 7.1.0)
95 | cocoapods (~> 1.13)
96 |
97 | RUBY VERSION
98 | ruby 2.6.10p210
99 |
100 | BUNDLED WITH
101 | 1.17.2
102 |
--------------------------------------------------------------------------------
/LICENSE-MIT:
--------------------------------------------------------------------------------
1 | Copyright (c) OpenJS Foundation and other contributors
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | 'Software'), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WebdriverIO Demo App for iOS and Android
2 |
3 | This app is built with React Native and will be used for test automation purposes for the [appium-boilerplate](https://github.com/webdriverio/appium-boilerplate).
4 |
5 | https://user-images.githubusercontent.com/11979740/118520294-3fb8e480-b73a-11eb-9100-dccecbb683cc.mov
6 |
7 | ## Downloads
8 | Different releases of the iOS and Android app can be downloaded [here](https://github.com/webdriverio/native-demo-app/releases)
9 |
10 | > [!NOTE]
11 | > The Android app can be installed on Android emulators and physical devices. The iOS app can **ONLY** be installed on iOS simulators. There is no build available for physical iOS devices due to not being able to install this app on physical iPhones. This is a (security) limitation from Apple.
12 |
13 | ## Features
14 | This app can/will be used for the [appium-boilerplate](https://github.com/webdriverio/appium-boilerplate) so (new) users
15 | of WebdriverIO and Appium can play around.
16 | How WebdriverIO and Appium can be used together can be found there, here you will only find the code to build the app.
17 |
18 | The app holds the following screens:
19 | - **:house: Home:** The intro of the app
20 | - **:spider_web: WebView:** Clicking on the WebView tab will open the WebdriverIO website (**only once**). It is created to test for
21 | example switching context and interacting with the WebView
22 | - **:closed_lock_with_key: Login:** This screen contains a simple Login / Sign Up screen with validations and alerts. If Touch/FaceId for iOS
23 | or Fingerprint for Android is enabled, then you will also be able to test that.
24 | - **:page_facing_up: Forms:** This screen holds some basic form elements to interact with like:
25 | - **Input**
26 | - **Switch**
27 | - **DropDown**
28 | - **Button**
29 | - **:pinching_hand: Swipe:** This screen will hold a carousel so horizontal swiping can be tested. It can also be used to test vertical
30 | swiping
31 | - **:pinching_hand: Drag:** This screen holds a simple puzzle. The puzzle can be solved by dragging the pieces into the main image.
32 |
33 | ## Contributing
34 | Please read [CONTRIBUTING.md](./docs/CONTRIBUTING.md) for details on our process for submitting pull requests to us or
35 | building an app release for Android Emulators/Real devices or an iOS Simulator.
36 |
37 | ## Versioning
38 | We use [SemVer](https://semver.org/) for versioning, see [VERSIONING.md](./docs/VERSIONING.md) for more information.
39 |
40 | ## Build With
41 | - [React Native](https://reactnative.dev/)
42 |
--------------------------------------------------------------------------------
/__tests__/App.test.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * @format
3 | */
4 |
5 | import 'react-native';
6 | import React from 'react';
7 | import App from '../src/App';
8 |
9 | // Note: import explicitly to use the types shipped with jest.
10 | import {it} from '@jest/globals';
11 |
12 | // Note: test renderer must be required after react-native.
13 | import renderer from 'react-test-renderer';
14 |
15 | it('renders correctly', () => {
16 | renderer.create();
17 | });
18 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.application"
2 | apply plugin: "org.jetbrains.kotlin.android"
3 | apply plugin: "com.facebook.react"
4 |
5 | /**
6 | * This is the configuration block to customize your React Native Android app.
7 | * By default you don't need to apply any configuration, just uncomment the lines you need.
8 | */
9 | react {
10 | /* Folders */
11 | // The root of your project, i.e. where "package.json" lives. Default is '..'
12 | // root = file("../")
13 | // The folder where the react-native NPM package is. Default is ../node_modules/react-native
14 | // reactNativeDir = file("../node_modules/react-native")
15 | // The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen
16 | // codegenDir = file("../node_modules/@react-native/codegen")
17 | // The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js
18 | // cliFile = file("../node_modules/react-native/cli.js")
19 |
20 | /* Variants */
21 | // The list of variants to that are debuggable. For those we're going to
22 | // skip the bundling of the JS bundle and the assets. By default is just 'debug'.
23 | // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants.
24 | // debuggableVariants = ["liteDebug", "prodDebug"]
25 |
26 | /* Bundling */
27 | // A list containing the node command and its flags. Default is just 'node'.
28 | // nodeExecutableAndArgs = ["node"]
29 | //
30 | // The command to run when bundling. By default is 'bundle'
31 | // bundleCommand = "ram-bundle"
32 | //
33 | // The path to the CLI configuration file. Default is empty.
34 | // bundleConfig = file(../rn-cli.config.js)
35 | //
36 | // The name of the generated asset file containing your JS bundle
37 | // bundleAssetName = "MyApplication.android.bundle"
38 | //
39 | // The entry file for bundle generation. Default is 'index.android.js' or 'index.js'
40 | // entryFile = file("../js/MyApplication.android.js")
41 | //
42 | // A list of extra flags to pass to the 'bundle' commands.
43 | // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle
44 | // extraPackagerArgs = []
45 |
46 | /* Hermes Commands */
47 | // The hermes compiler command to run. By default it is 'hermesc'
48 | // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc"
49 | //
50 | // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
51 | // hermesFlags = ["-O", "-output-source-map"]
52 | }
53 |
54 | /**
55 | * Set this to true to Run Proguard on Release builds to minify the Java bytecode.
56 | */
57 | def enableProguardInReleaseBuilds = false
58 |
59 | /**
60 | * The preferred build flavor of JavaScriptCore (JSC)
61 | *
62 | * For example, to use the international variant, you can use:
63 | * `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
64 | *
65 | * The international variant includes ICU i18n library and necessary data
66 | * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
67 | * give correct results when using with locales other than en-US. Note that
68 | * this variant is about 6MiB larger per architecture than default.
69 | */
70 | def jscFlavor = 'org.webkit:android-jsc:+'
71 |
72 | android {
73 | ndkVersion rootProject.ext.ndkVersion
74 | buildToolsVersion rootProject.ext.buildToolsVersion
75 | compileSdk rootProject.ext.compileSdkVersion
76 |
77 | namespace "com.wdiodemoapp"
78 | defaultConfig {
79 | applicationId "com.wdiodemoapp"
80 | minSdkVersion rootProject.ext.minSdkVersion
81 | targetSdkVersion rootProject.ext.targetSdkVersion
82 | versionCode 19
83 | versionName "1.0.8"
84 | }
85 | signingConfigs {
86 | debug {
87 | storeFile file('debug.keystore')
88 | storePassword 'android'
89 | keyAlias 'androiddebugkey'
90 | keyPassword 'android'
91 | }
92 | release {
93 | if (project.hasProperty('WDIO_NATIVE_APP_UPLOAD_STORE_FILE')) {
94 | storeFile file(WDIO_NATIVE_APP_UPLOAD_STORE_FILE)
95 | storePassword WDIO_NATIVE_APP_UPLOAD_STORE_PASSWORD
96 | keyAlias WDIO_NATIVE_APP_UPLOAD_KEY_ALIAS
97 | keyPassword WDIO_NATIVE_APP_UPLOAD_KEY_PASSWORD
98 | }
99 | }
100 | }
101 | buildTypes {
102 | debug {
103 | signingConfig signingConfigs.debug
104 | }
105 | release {
106 | // Caution! In production, you need to generate your own keystore file.
107 | // see https://reactnative.dev/docs/signed-apk-android.
108 | signingConfig signingConfigs.release
109 | minifyEnabled enableProguardInReleaseBuilds
110 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
111 | }
112 | }
113 | }
114 |
115 | dependencies {
116 | // The version of react-native is set by the React Native Gradle Plugin
117 | implementation("com.facebook.react:react-android")
118 | implementation("com.facebook.react:flipper-integration")
119 |
120 | if (hermesEnabled.toBoolean()) {
121 | implementation("com.facebook.react:hermes-android")
122 | } else {
123 | implementation jscFlavor
124 | }
125 | }
126 |
127 | apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
128 |
129 | // For react-native-vector-icons
130 | project.ext.vectoricons = [
131 | iconFontNames: [ 'MaterialIcons.ttf', 'MaterialCommunityIcons.ttf' ]
132 | ]
133 | apply from: file("../../node_modules/react-native-vector-icons/fonts.gradle")
--------------------------------------------------------------------------------
/android/app/debug.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/android/app/debug.keystore
--------------------------------------------------------------------------------
/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/wdiodemoapp/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.wdiodemoapp
2 | import expo.modules.ReactActivityDelegateWrapper
3 |
4 | import com.facebook.react.ReactActivity
5 | import com.facebook.react.ReactActivityDelegate
6 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
7 | import com.facebook.react.defaults.DefaultReactActivityDelegate
8 |
9 | // for react-navigation
10 | import android.os.Bundle;
11 |
12 | // for react-native-bootsplash
13 | import com.zoontek.rnbootsplash.RNBootSplash;
14 |
15 | class MainActivity : ReactActivity() {
16 |
17 | /**
18 | * Returns the name of the main component registered from JavaScript. This is used to schedule
19 | * rendering of the component.
20 | */
21 | override fun getMainComponentName(): String = "wdiodemoapp"
22 |
23 | /**
24 | * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate]
25 | * which allows you to enable New Architecture with a single boolean flags [fabricEnabled]
26 | */
27 | override fun createReactActivityDelegate(): ReactActivityDelegate =
28 | ReactActivityDelegateWrapper(this, BuildConfig.IS_NEW_ARCHITECTURE_ENABLED, DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled))
29 |
30 | /**
31 | * https://reactnavigation.org/docs/getting-started/#installing-dependencies-into-a-bare-react-native-project
32 | * https://github.com/zoontek/react-native-bootsplash?tab=readme-ov-file#android-1
33 | */
34 | override fun onCreate(savedInstanceState: Bundle?) {
35 | RNBootSplash.init(this, R.style.BootTheme) // ⬅️ initialize the splash screen
36 | super.onCreate(null) // super.onCreate(null) with react-native-screens
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/wdiodemoapp/MainApplication.kt:
--------------------------------------------------------------------------------
1 | package com.wdiodemoapp
2 | import android.content.res.Configuration
3 | import expo.modules.ApplicationLifecycleDispatcher
4 | import expo.modules.ReactNativeHostWrapper
5 |
6 | import android.app.Application
7 | import com.facebook.react.PackageList
8 | import com.facebook.react.ReactApplication
9 | import com.facebook.react.ReactHost
10 | import com.facebook.react.ReactNativeHost
11 | import com.facebook.react.ReactPackage
12 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
13 | import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
14 | import com.facebook.react.defaults.DefaultReactNativeHost
15 | import com.facebook.react.flipper.ReactNativeFlipper
16 | import com.facebook.soloader.SoLoader
17 |
18 | class MainApplication : Application(), ReactApplication {
19 |
20 | override val reactNativeHost: ReactNativeHost =
21 | ReactNativeHostWrapper(this, object : DefaultReactNativeHost(this) {
22 | override fun getPackages(): List {
23 | // Packages that cannot be autolinked yet can be added manually here, for example:
24 | // packages.add(new MyReactNativePackage());
25 | return PackageList(this).packages
26 | }
27 |
28 | override fun getJSMainModuleName(): String = "index"
29 |
30 | override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
31 |
32 | override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
33 | override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
34 | })
35 |
36 | override val reactHost: ReactHost
37 | get() = getDefaultReactHost(this.applicationContext, reactNativeHost)
38 |
39 | override fun onCreate() {
40 | super.onCreate()
41 | SoLoader.init(this, false)
42 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
43 | // If you opted-in for the New Architecture, we load the native entry point for this app.
44 | load()
45 | }
46 | ReactNativeFlipper.initializeFlipper(this, reactNativeHost.reactInstanceManager)
47 | ApplicationLifecycleDispatcher.onApplicationCreate(this)
48 | }
49 |
50 | override fun onConfigurationChanged(newConfig: Configuration) {
51 | super.onConfigurationChanged(newConfig)
52 | ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig)
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-hdpi/bootsplash_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/android/app/src/main/res/drawable-hdpi/bootsplash_logo.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-mdpi/bootsplash_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/android/app/src/main/res/drawable-mdpi/bootsplash_logo.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-xhdpi/bootsplash_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/android/app/src/main/res/drawable-xhdpi/bootsplash_logo.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-xxhdpi/bootsplash_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/android/app/src/main/res/drawable-xxhdpi/bootsplash_logo.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-xxxhdpi/bootsplash_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/android/app/src/main/res/drawable-xxxhdpi/bootsplash_logo.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/rn_edit_text_material.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
21 |
22 |
23 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 | #1c1d20
3 |
4 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | wdiodemoapp
3 |
4 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/android/app/wdio-native-app-upload-key.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/android/app/wdio-native-app-upload-key.keystore
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext {
3 | buildToolsVersion = "34.0.0"
4 | minSdkVersion = 21
5 | compileSdkVersion = 34
6 | targetSdkVersion = 34
7 | ndkVersion = "25.1.8937393"
8 | kotlinVersion = "1.8.0"
9 | }
10 | repositories {
11 | google()
12 | mavenCentral()
13 | }
14 | dependencies {
15 | classpath("com.android.tools.build:gradle")
16 | classpath("com.facebook.react:react-native-gradle-plugin")
17 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
18 | }
19 | }
20 |
21 | apply plugin: "com.facebook.react.rootproject"
22 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | # AndroidX package structure to make it clearer which packages are bundled with the
21 | # Android operating system, and which are packaged with your app's APK
22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
23 | android.useAndroidX=true
24 | # Automatically convert third-party libraries to use AndroidX
25 | android.enableJetifier=true
26 |
27 | # Use this property to specify which architecture you want to build.
28 | # You can also override it from the CLI using
29 | # ./gradlew -PreactNativeArchitectures=x86_64
30 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
31 |
32 | # Use this property to enable support to the new architecture.
33 | # This will allow you to use TurboModules and the Fabric render in
34 | # your application. You should enable this flag either if you want
35 | # to write custom TurboModules/Fabric components OR use libraries that
36 | # are providing them.
37 | newArchEnabled=false
38 |
39 | # Use this property to enable or disable the Hermes JS engine.
40 | # If set to false, you will be using JSC instead.
41 | hermesEnabled=true
42 |
43 | # For signing the native app with a dummy keystore
44 | # https://reactnative.dev/docs/signed-apk-android#setting-up-gradle-variables
45 | WDIO_NATIVE_APP_UPLOAD_STORE_FILE=wdio-native-app-upload-key.keystore
46 | WDIO_NATIVE_APP_UPLOAD_KEY_ALIAS=wdio-native-app-alias
47 | WDIO_NATIVE_APP_UPLOAD_STORE_PASSWORD=wdio-native-app
48 | WDIO_NATIVE_APP_UPLOAD_KEY_PASSWORD=wdio-native-app
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Copyright © 2015-2021 the original authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | #
21 | # Gradle start up script for POSIX generated by Gradle.
22 | #
23 | # Important for running:
24 | #
25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
26 | # noncompliant, but you have some other compliant shell such as ksh or
27 | # bash, then to run this script, type that shell name before the whole
28 | # command line, like:
29 | #
30 | # ksh Gradle
31 | #
32 | # Busybox and similar reduced shells will NOT work, because this script
33 | # requires all of these POSIX shell features:
34 | # * functions;
35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
37 | # * compound commands having a testable exit status, especially «case»;
38 | # * various built-in commands including «command», «set», and «ulimit».
39 | #
40 | # Important for patching:
41 | #
42 | # (2) This script targets any POSIX shell, so it avoids extensions provided
43 | # by Bash, Ksh, etc; in particular arrays are avoided.
44 | #
45 | # The "traditional" practice of packing multiple parameters into a
46 | # space-separated string is a well documented source of bugs and security
47 | # problems, so this is (mostly) avoided, by progressively accumulating
48 | # options in "$@", and eventually passing that to Java.
49 | #
50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
52 | # see the in-line comments for details.
53 | #
54 | # There are tweaks for specific operating systems such as AIX, CygWin,
55 | # Darwin, MinGW, and NonStop.
56 | #
57 | # (3) This script is generated from the Groovy template
58 | # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
59 | # within the Gradle project.
60 | #
61 | # You can find Gradle at https://github.com/gradle/gradle/.
62 | #
63 | ##############################################################################
64 |
65 | # Attempt to set APP_HOME
66 |
67 | # Resolve links: $0 may be a link
68 | app_path=$0
69 |
70 | # Need this for daisy-chained symlinks.
71 | while
72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
73 | [ -h "$app_path" ]
74 | do
75 | ls=$( ls -ld "$app_path" )
76 | link=${ls#*' -> '}
77 | case $link in #(
78 | /*) app_path=$link ;; #(
79 | *) app_path=$APP_HOME$link ;;
80 | esac
81 | done
82 |
83 | # This is normally unused
84 | # shellcheck disable=SC2034
85 | APP_BASE_NAME=${0##*/}
86 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
87 | APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
88 |
89 | # Use the maximum available, or set MAX_FD != -1 to use that value.
90 | MAX_FD=maximum
91 |
92 | warn () {
93 | echo "$*"
94 | } >&2
95 |
96 | die () {
97 | echo
98 | echo "$*"
99 | echo
100 | exit 1
101 | } >&2
102 |
103 | # OS specific support (must be 'true' or 'false').
104 | cygwin=false
105 | msys=false
106 | darwin=false
107 | nonstop=false
108 | case "$( uname )" in #(
109 | CYGWIN* ) cygwin=true ;; #(
110 | Darwin* ) darwin=true ;; #(
111 | MSYS* | MINGW* ) msys=true ;; #(
112 | NONSTOP* ) nonstop=true ;;
113 | esac
114 |
115 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
116 |
117 |
118 | # Determine the Java command to use to start the JVM.
119 | if [ -n "$JAVA_HOME" ] ; then
120 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
121 | # IBM's JDK on AIX uses strange locations for the executables
122 | JAVACMD=$JAVA_HOME/jre/sh/java
123 | else
124 | JAVACMD=$JAVA_HOME/bin/java
125 | fi
126 | if [ ! -x "$JAVACMD" ] ; then
127 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
128 |
129 | Please set the JAVA_HOME variable in your environment to match the
130 | location of your Java installation."
131 | fi
132 | else
133 | JAVACMD=java
134 | if ! command -v java >/dev/null 2>&1
135 | then
136 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
137 |
138 | Please set the JAVA_HOME variable in your environment to match the
139 | location of your Java installation."
140 | fi
141 | fi
142 |
143 | # Increase the maximum file descriptors if we can.
144 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
145 | case $MAX_FD in #(
146 | max*)
147 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
148 | # shellcheck disable=SC3045
149 | MAX_FD=$( ulimit -H -n ) ||
150 | warn "Could not query maximum file descriptor limit"
151 | esac
152 | case $MAX_FD in #(
153 | '' | soft) :;; #(
154 | *)
155 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
156 | # shellcheck disable=SC3045
157 | ulimit -n "$MAX_FD" ||
158 | warn "Could not set maximum file descriptor limit to $MAX_FD"
159 | esac
160 | fi
161 |
162 | # Collect all arguments for the java command, stacking in reverse order:
163 | # * args from the command line
164 | # * the main class name
165 | # * -classpath
166 | # * -D...appname settings
167 | # * --module-path (only if needed)
168 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
169 |
170 | # For Cygwin or MSYS, switch paths to Windows format before running java
171 | if "$cygwin" || "$msys" ; then
172 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
173 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
174 |
175 | JAVACMD=$( cygpath --unix "$JAVACMD" )
176 |
177 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
178 | for arg do
179 | if
180 | case $arg in #(
181 | -*) false ;; # don't mess with options #(
182 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
183 | [ -e "$t" ] ;; #(
184 | *) false ;;
185 | esac
186 | then
187 | arg=$( cygpath --path --ignore --mixed "$arg" )
188 | fi
189 | # Roll the args list around exactly as many times as the number of
190 | # args, so each arg winds up back in the position where it started, but
191 | # possibly modified.
192 | #
193 | # NB: a `for` loop captures its iteration list before it begins, so
194 | # changing the positional parameters here affects neither the number of
195 | # iterations, nor the values presented in `arg`.
196 | shift # remove old arg
197 | set -- "$@" "$arg" # push replacement arg
198 | done
199 | fi
200 |
201 |
202 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
203 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
204 |
205 | # Collect all arguments for the java command;
206 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
207 | # shell script including quotes and variable substitutions, so put them in
208 | # double quotes to make sure that they get re-expanded; and
209 | # * put everything else in single quotes, so that it's not re-expanded.
210 |
211 | set -- \
212 | "-Dorg.gradle.appname=$APP_BASE_NAME" \
213 | -classpath "$CLASSPATH" \
214 | org.gradle.wrapper.GradleWrapperMain \
215 | "$@"
216 |
217 | # Stop when "xargs" is not available.
218 | if ! command -v xargs >/dev/null 2>&1
219 | then
220 | die "xargs is not available"
221 | fi
222 |
223 | # Use "xargs" to parse quoted args.
224 | #
225 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
226 | #
227 | # In Bash we could simply go:
228 | #
229 | # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
230 | # set -- "${ARGS[@]}" "$@"
231 | #
232 | # but POSIX shell has neither arrays nor command substitution, so instead we
233 | # post-process each arg (as a line of input to sed) to backslash-escape any
234 | # character that might be a shell metacharacter, then use eval to reverse
235 | # that process (while maintaining the separation between arguments), and wrap
236 | # the whole thing up as a single "set" statement.
237 | #
238 | # This will of course break if any of these variables contains a newline or
239 | # an unmatched quote.
240 | #
241 |
242 | eval "set -- $(
243 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
244 | xargs -n1 |
245 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
246 | tr '\n' ' '
247 | )" '"$@"'
248 |
249 | exec "$JAVACMD" "$@"
250 |
--------------------------------------------------------------------------------
/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | @rem This is normally unused
30 | set APP_BASE_NAME=%~n0
31 | set APP_HOME=%DIRNAME%
32 |
33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
35 |
36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
38 |
39 | @rem Find java.exe
40 | if defined JAVA_HOME goto findJavaFromJavaHome
41 |
42 | set JAVA_EXE=java.exe
43 | %JAVA_EXE% -version >NUL 2>&1
44 | if %ERRORLEVEL% equ 0 goto execute
45 |
46 | echo.
47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
48 | echo.
49 | echo Please set the JAVA_HOME variable in your environment to match the
50 | echo location of your Java installation.
51 |
52 | goto fail
53 |
54 | :findJavaFromJavaHome
55 | set JAVA_HOME=%JAVA_HOME:"=%
56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
57 |
58 | if exist "%JAVA_EXE%" goto execute
59 |
60 | echo.
61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
62 | echo.
63 | echo Please set the JAVA_HOME variable in your environment to match the
64 | echo location of your Java installation.
65 |
66 | goto fail
67 |
68 | :execute
69 | @rem Setup the command line
70 |
71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
72 |
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if %ERRORLEVEL% equ 0 goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | set EXIT_CODE=%ERRORLEVEL%
85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
87 | exit /b %EXIT_CODE%
88 |
89 | :mainEnd
90 | if "%OS%"=="Windows_NT" endlocal
91 |
92 | :omega
93 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'wdiodemoapp'
2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
3 | include ':app'
4 | includeBuild('../node_modules/@react-native/gradle-plugin')
5 |
6 | apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle")
7 | useExpoModules()
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ['module:@react-native/babel-preset'],
3 | plugins: ['react-native-reanimated/plugin'],
4 | };
5 |
--------------------------------------------------------------------------------
/docs/VERSIONING.md:
--------------------------------------------------------------------------------
1 | # Versioning the App
2 |
3 | Versioning the app needs to be a manual step. Follow the instructions below to update the versions
4 |
5 | ## Step 1: Determine build and version number
6 | Determine the **CURRENT** build and the version number of the app. You can find the current build number for:
7 | - **Android:** Search in the file [android/app/build.gradle](../android/app/build.gradle), look for the
8 | `defaultConfig` and then `versionCode`
9 | - **iOS:** Search in the file
10 | [ios/wdioNativeDemoApp.xcodeproj/project.pbxproj](../ios/wdioNativeDemoApp.xcodeproj/project.pbxproj) and look for
11 | `CURRENT_PROJECT_VERSION`
12 |
13 | The version number can be found in the [`package.json`](../package.json)-file.
14 |
15 | ## Step 2: Run React Native Versioning
16 | > **NOTE:** This step will only increase the build/version numbers in the app, **NOT** the version number of the
17 | > project, see [step 4](#step-4-create-a-new-release) for that.
18 |
19 | We use `react-native-versioning` to update the build and version number in the app. Use the build and version from
20 | [step 1](#step-1-determine-build-and-version-number) and increase the buildnumber with 1, and the version number
21 | according to [SemVer](https://semver.org/).
22 |
23 | ### Usage
24 | npx react-native-versioning \
25 | -t --target \
26 | -b --build \
27 | --android-only \
28 | --ios-only
29 |
30 | ### Example
31 | npx react-native-versioning --target=2.1.1
32 | npx react-native-versioning --build=17
33 | npx react-native-versioning --build=18 --ios-only
34 | npx react-native-versioning --target=2.3 --build=16 --android-only
35 |
36 | ## Step 3: Create a PR
37 | Create a version bump PR with the adjusted versions as explained above
38 |
39 | > **NOTE:** The version in the package.json and the actual release will be explained in
40 | > [step 4](#step-4-create-a-new-release).
41 |
42 | ## Step 4: Create a new release
43 | When step 1 till 3 are executed we need to create a new release. Make sure that you are on the `main`-branch and all
44 | changes have been committed/pushed. Then run the following command
45 |
46 | yarn release
47 |
48 | This will show an interactive UI to make a new release. See [np](https://github.com/sindresorhus/np#readme) for more
49 | information. Make sure you follow [SemVer](https://semver.org/) to target the release properly.
50 |
51 | `yarn release` will also automatically open GutHub on the releases page with a draft. Add the things there that are new.
52 | Before you upload the assets you need to adjust the app names. The Appname for Android will automatically be created
53 | when you build a new release, it will look like this
54 |
55 | Android-NativeDemoApp-{x.y.z}.apk
56 |
57 | For iOS you first need to zip the file and then change the name from
58 |
59 | wdioNativeDemoApp.app
60 |
61 | to
62 |
63 | iOS-Simulator-NativeDemoApp-{x.y.z}.app.zip
64 |
65 | You can then upload the assets and release a new version.
66 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @format
3 | */
4 |
5 | import {AppRegistry} from 'react-native';
6 | import App from './src/App';
7 | import {name as appName} from './src/app.json';
8 |
9 | AppRegistry.registerComponent(appName, () => App);
10 |
--------------------------------------------------------------------------------
/ios/.xcode.env:
--------------------------------------------------------------------------------
1 | # This `.xcode.env` file is versioned and is used to source the environment
2 | # used when running script phases inside Xcode.
3 | # To customize your local environment, you can create an `.xcode.env.local`
4 | # file that is not versioned.
5 |
6 | # NODE_BINARY variable contains the PATH to the node executable.
7 | #
8 | # Customize the NODE_BINARY variable here.
9 | # For example, to use nvm with brew, add the following line
10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use
11 | export NODE_BINARY=$(command -v node)
12 |
--------------------------------------------------------------------------------
/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Needed for GHA to work
2 | use_modular_headers!
3 |
4 | require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking")
5 | # Resolve react_native_pods.rb with node to allow for hoisting
6 | require Pod::Executable.execute_command('node', ['-p',
7 | 'require.resolve(
8 | "react-native/scripts/react_native_pods.rb",
9 | {paths: [process.argv[1]]},
10 | )', __dir__]).strip
11 |
12 | platform :ios, min_ios_version_supported
13 | prepare_react_native_project!
14 |
15 | # If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set.
16 | # because `react-native-flipper` depends on (FlipperKit,...) that will be excluded
17 | #
18 | # To fix this you can also exclude `react-native-flipper` using a `react-native.config.js`
19 | # ```js
20 | # module.exports = {
21 | # dependencies: {
22 | # ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}),
23 | # ```
24 | flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled
25 |
26 | linkage = ENV['USE_FRAMEWORKS']
27 | if linkage != nil
28 | Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
29 | use_frameworks! :linkage => linkage.to_sym
30 | end
31 |
32 | target 'wdiodemoapp' do
33 | use_expo_modules!
34 | post_integrate do |installer|
35 | begin
36 | expo_patch_react_imports!(installer)
37 | rescue => e
38 | Pod::UI.warn e
39 | end
40 | end
41 | config = use_native_modules!
42 |
43 | use_react_native!(
44 | :path => config[:reactNativePath],
45 | # Enables Flipper.
46 | #
47 | # Note that if you have use_frameworks! enabled, Flipper will not work and
48 | # you should disable the next line.
49 | :flipper_configuration => flipper_config,
50 | # An absolute path to your application root.
51 | :app_path => "#{Pod::Config.instance.installation_root}/.."
52 | )
53 |
54 | target 'wdiodemoappTests' do
55 | inherit! :complete
56 | # Pods for testing
57 | end
58 |
59 | post_install do |installer|
60 | # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202
61 | react_native_post_install(
62 | installer,
63 | config[:reactNativePath],
64 | :mac_catalyst_enabled => false
65 | )
66 | end
67 | end
68 |
--------------------------------------------------------------------------------
/ios/wdiodemoapp.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 54;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 00E356F31AD99517003FC87E /* wdiodemoappTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* wdiodemoappTests.m */; };
11 | 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; };
12 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13 | 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
14 | 1F62737D24ED11D20F93E40B /* libPods-wdiodemoapp-wdiodemoappTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C93534EE04F58941FEE832FB /* libPods-wdiodemoapp-wdiodemoappTests.a */; };
15 | 546209F9C9ECC4F0B7CC0FD0 /* libPods-wdiodemoapp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CE57BDCF00D03C18BDDDB78 /* libPods-wdiodemoapp.a */; };
16 | 58AC821722C8E5AAF95135DD /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BC6FAAE5D79662B491A1BE8 /* ExpoModulesProvider.swift */; };
17 | 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
18 | 8834A2D12B3AAAB2001348FD /* BootSplash.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8834A2D02B3AAAB2001348FD /* BootSplash.storyboard */; };
19 | 88DBFB312B38C2AF007FB243 /* MaterialIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 88DBFB1E2B38C2AF007FB243 /* MaterialIcons.ttf */; };
20 | 88DBFB362B39E532007FB243 /* MaterialCommunityIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 88DBFB352B39E532007FB243 /* MaterialCommunityIcons.ttf */; };
21 | D58558CCE85696350949AABD /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E4A597DAAD2ABA17A269985 /* ExpoModulesProvider.swift */; };
22 | /* End PBXBuildFile section */
23 |
24 | /* Begin PBXContainerItemProxy section */
25 | 00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = {
26 | isa = PBXContainerItemProxy;
27 | containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
28 | proxyType = 1;
29 | remoteGlobalIDString = 13B07F861A680F5B00A75B9A;
30 | remoteInfo = wdiodemoapp;
31 | };
32 | /* End PBXContainerItemProxy section */
33 |
34 | /* Begin PBXFileReference section */
35 | 00E356EE1AD99517003FC87E /* wdiodemoappTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = wdiodemoappTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
36 | 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
37 | 00E356F21AD99517003FC87E /* wdiodemoappTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = wdiodemoappTests.m; sourceTree = ""; };
38 | 13B07F961A680F5B00A75B9A /* wdiodemoapp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = wdiodemoapp.app; sourceTree = BUILT_PRODUCTS_DIR; };
39 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = wdiodemoapp/AppDelegate.h; sourceTree = ""; };
40 | 13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = wdiodemoapp/AppDelegate.mm; sourceTree = ""; };
41 | 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = wdiodemoapp/Images.xcassets; sourceTree = ""; };
42 | 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = wdiodemoapp/Info.plist; sourceTree = ""; };
43 | 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = wdiodemoapp/main.m; sourceTree = ""; };
44 | 25BA9D4427943074799979B9 /* Pods-wdiodemoapp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-wdiodemoapp.debug.xcconfig"; path = "Target Support Files/Pods-wdiodemoapp/Pods-wdiodemoapp.debug.xcconfig"; sourceTree = ""; };
45 | 4CE57BDCF00D03C18BDDDB78 /* libPods-wdiodemoapp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-wdiodemoapp.a"; sourceTree = BUILT_PRODUCTS_DIR; };
46 | 53094DCAE92584D148E207E3 /* Pods-wdiodemoapp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-wdiodemoapp.release.xcconfig"; path = "Target Support Files/Pods-wdiodemoapp/Pods-wdiodemoapp.release.xcconfig"; sourceTree = ""; };
47 | 5BC6FAAE5D79662B491A1BE8 /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-wdiodemoapp-wdiodemoappTests/ExpoModulesProvider.swift"; sourceTree = ""; };
48 | 6E4A597DAAD2ABA17A269985 /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-wdiodemoapp/ExpoModulesProvider.swift"; sourceTree = ""; };
49 | 7C0C6C004693AFA68A120E17 /* Pods-wdiodemoapp-wdiodemoappTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-wdiodemoapp-wdiodemoappTests.release.xcconfig"; path = "Target Support Files/Pods-wdiodemoapp-wdiodemoappTests/Pods-wdiodemoapp-wdiodemoappTests.release.xcconfig"; sourceTree = ""; };
50 | 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = wdiodemoapp/LaunchScreen.storyboard; sourceTree = ""; };
51 | 8834A2D02B3AAAB2001348FD /* BootSplash.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = BootSplash.storyboard; path = wdiodemoapp/BootSplash.storyboard; sourceTree = ""; };
52 | 88DBFB1E2B38C2AF007FB243 /* MaterialIcons.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = MaterialIcons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/MaterialIcons.ttf"; sourceTree = ""; };
53 | 88DBFB352B39E532007FB243 /* MaterialCommunityIcons.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = MaterialCommunityIcons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/MaterialCommunityIcons.ttf"; sourceTree = ""; };
54 | B098E6C9A70C7148138F766F /* Pods-wdiodemoapp-wdiodemoappTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-wdiodemoapp-wdiodemoappTests.debug.xcconfig"; path = "Target Support Files/Pods-wdiodemoapp-wdiodemoappTests/Pods-wdiodemoapp-wdiodemoappTests.debug.xcconfig"; sourceTree = ""; };
55 | C93534EE04F58941FEE832FB /* libPods-wdiodemoapp-wdiodemoappTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-wdiodemoapp-wdiodemoappTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
56 | ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
57 | /* End PBXFileReference section */
58 |
59 | /* Begin PBXFrameworksBuildPhase section */
60 | 00E356EB1AD99517003FC87E /* Frameworks */ = {
61 | isa = PBXFrameworksBuildPhase;
62 | buildActionMask = 2147483647;
63 | files = (
64 | 1F62737D24ED11D20F93E40B /* libPods-wdiodemoapp-wdiodemoappTests.a in Frameworks */,
65 | );
66 | runOnlyForDeploymentPostprocessing = 0;
67 | };
68 | 13B07F8C1A680F5B00A75B9A /* Frameworks */ = {
69 | isa = PBXFrameworksBuildPhase;
70 | buildActionMask = 2147483647;
71 | files = (
72 | 546209F9C9ECC4F0B7CC0FD0 /* libPods-wdiodemoapp.a in Frameworks */,
73 | );
74 | runOnlyForDeploymentPostprocessing = 0;
75 | };
76 | /* End PBXFrameworksBuildPhase section */
77 |
78 | /* Begin PBXGroup section */
79 | 00E356EF1AD99517003FC87E /* wdiodemoappTests */ = {
80 | isa = PBXGroup;
81 | children = (
82 | 00E356F21AD99517003FC87E /* wdiodemoappTests.m */,
83 | 00E356F01AD99517003FC87E /* Supporting Files */,
84 | );
85 | path = wdiodemoappTests;
86 | sourceTree = "";
87 | };
88 | 00E356F01AD99517003FC87E /* Supporting Files */ = {
89 | isa = PBXGroup;
90 | children = (
91 | 00E356F11AD99517003FC87E /* Info.plist */,
92 | );
93 | name = "Supporting Files";
94 | sourceTree = "";
95 | };
96 | 13B07FAE1A68108700A75B9A /* wdiodemoapp */ = {
97 | isa = PBXGroup;
98 | children = (
99 | 88DBFB0E2B38C251007FB243 /* Fonts */,
100 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */,
101 | 13B07FB01A68108700A75B9A /* AppDelegate.mm */,
102 | 13B07FB51A68108700A75B9A /* Images.xcassets */,
103 | 13B07FB61A68108700A75B9A /* Info.plist */,
104 | 8834A2D02B3AAAB2001348FD /* BootSplash.storyboard */,
105 | 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */,
106 | 13B07FB71A68108700A75B9A /* main.m */,
107 | );
108 | name = wdiodemoapp;
109 | sourceTree = "";
110 | };
111 | 2D16E6871FA4F8E400B85C8A /* Frameworks */ = {
112 | isa = PBXGroup;
113 | children = (
114 | ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
115 | 4CE57BDCF00D03C18BDDDB78 /* libPods-wdiodemoapp.a */,
116 | C93534EE04F58941FEE832FB /* libPods-wdiodemoapp-wdiodemoappTests.a */,
117 | );
118 | name = Frameworks;
119 | sourceTree = "";
120 | };
121 | 832341AE1AAA6A7D00B99B32 /* Libraries */ = {
122 | isa = PBXGroup;
123 | children = (
124 | );
125 | name = Libraries;
126 | sourceTree = "";
127 | };
128 | 83CBB9F61A601CBA00E9B192 = {
129 | isa = PBXGroup;
130 | children = (
131 | 13B07FAE1A68108700A75B9A /* wdiodemoapp */,
132 | 832341AE1AAA6A7D00B99B32 /* Libraries */,
133 | 00E356EF1AD99517003FC87E /* wdiodemoappTests */,
134 | 83CBBA001A601CBA00E9B192 /* Products */,
135 | 2D16E6871FA4F8E400B85C8A /* Frameworks */,
136 | BBD78D7AC51CEA395F1C20DB /* Pods */,
137 | E00B43E4BD1FDF9D3D5D173F /* ExpoModulesProviders */,
138 | );
139 | indentWidth = 2;
140 | sourceTree = "";
141 | tabWidth = 2;
142 | usesTabs = 0;
143 | };
144 | 83CBBA001A601CBA00E9B192 /* Products */ = {
145 | isa = PBXGroup;
146 | children = (
147 | 13B07F961A680F5B00A75B9A /* wdiodemoapp.app */,
148 | 00E356EE1AD99517003FC87E /* wdiodemoappTests.xctest */,
149 | );
150 | name = Products;
151 | sourceTree = "";
152 | };
153 | 88DBFB0E2B38C251007FB243 /* Fonts */ = {
154 | isa = PBXGroup;
155 | children = (
156 | 88DBFB352B39E532007FB243 /* MaterialCommunityIcons.ttf */,
157 | 88DBFB1E2B38C2AF007FB243 /* MaterialIcons.ttf */,
158 | );
159 | name = Fonts;
160 | sourceTree = "";
161 | };
162 | A1B5921F6750FA2155A99EBE /* wdiodemoappTests */ = {
163 | isa = PBXGroup;
164 | children = (
165 | 5BC6FAAE5D79662B491A1BE8 /* ExpoModulesProvider.swift */,
166 | );
167 | name = wdiodemoappTests;
168 | sourceTree = "";
169 | };
170 | BBD78D7AC51CEA395F1C20DB /* Pods */ = {
171 | isa = PBXGroup;
172 | children = (
173 | 25BA9D4427943074799979B9 /* Pods-wdiodemoapp.debug.xcconfig */,
174 | 53094DCAE92584D148E207E3 /* Pods-wdiodemoapp.release.xcconfig */,
175 | B098E6C9A70C7148138F766F /* Pods-wdiodemoapp-wdiodemoappTests.debug.xcconfig */,
176 | 7C0C6C004693AFA68A120E17 /* Pods-wdiodemoapp-wdiodemoappTests.release.xcconfig */,
177 | );
178 | path = Pods;
179 | sourceTree = "";
180 | };
181 | E00B43E4BD1FDF9D3D5D173F /* ExpoModulesProviders */ = {
182 | isa = PBXGroup;
183 | children = (
184 | FEFA9EAC8D7DB45DCDC5D9CE /* wdiodemoapp */,
185 | A1B5921F6750FA2155A99EBE /* wdiodemoappTests */,
186 | );
187 | name = ExpoModulesProviders;
188 | sourceTree = "";
189 | };
190 | FEFA9EAC8D7DB45DCDC5D9CE /* wdiodemoapp */ = {
191 | isa = PBXGroup;
192 | children = (
193 | 6E4A597DAAD2ABA17A269985 /* ExpoModulesProvider.swift */,
194 | );
195 | name = wdiodemoapp;
196 | sourceTree = "";
197 | };
198 | /* End PBXGroup section */
199 |
200 | /* Begin PBXNativeTarget section */
201 | 00E356ED1AD99517003FC87E /* wdiodemoappTests */ = {
202 | isa = PBXNativeTarget;
203 | buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "wdiodemoappTests" */;
204 | buildPhases = (
205 | C91A6693AD82ACBB515F9253 /* [CP] Check Pods Manifest.lock */,
206 | C48BD2FE476FB58A7F908727 /* [Expo] Configure project */,
207 | 00E356EA1AD99517003FC87E /* Sources */,
208 | 00E356EB1AD99517003FC87E /* Frameworks */,
209 | 00E356EC1AD99517003FC87E /* Resources */,
210 | 7983DC114F19245121DDB2D2 /* [CP] Embed Pods Frameworks */,
211 | 404F7AA0A3BCBA96DB2654A7 /* [CP] Copy Pods Resources */,
212 | );
213 | buildRules = (
214 | );
215 | dependencies = (
216 | 00E356F51AD99517003FC87E /* PBXTargetDependency */,
217 | );
218 | name = wdiodemoappTests;
219 | productName = wdiodemoappTests;
220 | productReference = 00E356EE1AD99517003FC87E /* wdiodemoappTests.xctest */;
221 | productType = "com.apple.product-type.bundle.unit-test";
222 | };
223 | 13B07F861A680F5B00A75B9A /* wdiodemoapp */ = {
224 | isa = PBXNativeTarget;
225 | buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "wdiodemoapp" */;
226 | buildPhases = (
227 | E1A3D16B8054AE52DD3BE26C /* [CP] Check Pods Manifest.lock */,
228 | 32B3C91BE3DAFC9CD77A7573 /* [Expo] Configure project */,
229 | 13B07F871A680F5B00A75B9A /* Sources */,
230 | 13B07F8C1A680F5B00A75B9A /* Frameworks */,
231 | 13B07F8E1A680F5B00A75B9A /* Resources */,
232 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
233 | 916D8445876CDD9226BE7078 /* [CP] Embed Pods Frameworks */,
234 | B0F225A2A1D795AC9364D4A1 /* [CP] Copy Pods Resources */,
235 | );
236 | buildRules = (
237 | );
238 | dependencies = (
239 | );
240 | name = wdiodemoapp;
241 | productName = wdiodemoapp;
242 | productReference = 13B07F961A680F5B00A75B9A /* wdiodemoapp.app */;
243 | productType = "com.apple.product-type.application";
244 | };
245 | /* End PBXNativeTarget section */
246 |
247 | /* Begin PBXProject section */
248 | 83CBB9F71A601CBA00E9B192 /* Project object */ = {
249 | isa = PBXProject;
250 | attributes = {
251 | LastUpgradeCheck = 1210;
252 | TargetAttributes = {
253 | 00E356ED1AD99517003FC87E = {
254 | CreatedOnToolsVersion = 6.2;
255 | TestTargetID = 13B07F861A680F5B00A75B9A;
256 | };
257 | 13B07F861A680F5B00A75B9A = {
258 | LastSwiftMigration = 1120;
259 | };
260 | };
261 | };
262 | buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "wdiodemoapp" */;
263 | compatibilityVersion = "Xcode 12.0";
264 | developmentRegion = en;
265 | hasScannedForEncodings = 0;
266 | knownRegions = (
267 | en,
268 | Base,
269 | );
270 | mainGroup = 83CBB9F61A601CBA00E9B192;
271 | productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
272 | projectDirPath = "";
273 | projectRoot = "";
274 | targets = (
275 | 13B07F861A680F5B00A75B9A /* wdiodemoapp */,
276 | 00E356ED1AD99517003FC87E /* wdiodemoappTests */,
277 | );
278 | };
279 | /* End PBXProject section */
280 |
281 | /* Begin PBXResourcesBuildPhase section */
282 | 00E356EC1AD99517003FC87E /* Resources */ = {
283 | isa = PBXResourcesBuildPhase;
284 | buildActionMask = 2147483647;
285 | files = (
286 | );
287 | runOnlyForDeploymentPostprocessing = 0;
288 | };
289 | 13B07F8E1A680F5B00A75B9A /* Resources */ = {
290 | isa = PBXResourcesBuildPhase;
291 | buildActionMask = 2147483647;
292 | files = (
293 | 8834A2D12B3AAAB2001348FD /* BootSplash.storyboard in Resources */,
294 | 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */,
295 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
296 | 88DBFB362B39E532007FB243 /* MaterialCommunityIcons.ttf in Resources */,
297 | 88DBFB312B38C2AF007FB243 /* MaterialIcons.ttf in Resources */,
298 | );
299 | runOnlyForDeploymentPostprocessing = 0;
300 | };
301 | /* End PBXResourcesBuildPhase section */
302 |
303 | /* Begin PBXShellScriptBuildPhase section */
304 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = {
305 | isa = PBXShellScriptBuildPhase;
306 | buildActionMask = 2147483647;
307 | files = (
308 | );
309 | inputPaths = (
310 | "$(SRCROOT)/.xcode.env.local",
311 | "$(SRCROOT)/.xcode.env",
312 | );
313 | name = "Bundle React Native code and images";
314 | outputPaths = (
315 | );
316 | runOnlyForDeploymentPostprocessing = 0;
317 | shellPath = /bin/sh;
318 | shellScript = "set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n";
319 | };
320 | 32B3C91BE3DAFC9CD77A7573 /* [Expo] Configure project */ = {
321 | isa = PBXShellScriptBuildPhase;
322 | alwaysOutOfDate = 1;
323 | buildActionMask = 2147483647;
324 | files = (
325 | );
326 | inputFileListPaths = (
327 | );
328 | inputPaths = (
329 | );
330 | name = "[Expo] Configure project";
331 | outputFileListPaths = (
332 | );
333 | outputPaths = (
334 | );
335 | runOnlyForDeploymentPostprocessing = 0;
336 | shellPath = /bin/sh;
337 | shellScript = "# This script configures Expo modules and generates the modules provider file.\nbash -l -c \"./Pods/Target\\ Support\\ Files/Pods-wdiodemoapp/expo-configure-project.sh\"\n";
338 | };
339 | 404F7AA0A3BCBA96DB2654A7 /* [CP] Copy Pods Resources */ = {
340 | isa = PBXShellScriptBuildPhase;
341 | buildActionMask = 2147483647;
342 | files = (
343 | );
344 | inputFileListPaths = (
345 | "${PODS_ROOT}/Target Support Files/Pods-wdiodemoapp-wdiodemoappTests/Pods-wdiodemoapp-wdiodemoappTests-resources-${CONFIGURATION}-input-files.xcfilelist",
346 | );
347 | name = "[CP] Copy Pods Resources";
348 | outputFileListPaths = (
349 | "${PODS_ROOT}/Target Support Files/Pods-wdiodemoapp-wdiodemoappTests/Pods-wdiodemoapp-wdiodemoappTests-resources-${CONFIGURATION}-output-files.xcfilelist",
350 | );
351 | runOnlyForDeploymentPostprocessing = 0;
352 | shellPath = /bin/sh;
353 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-wdiodemoapp-wdiodemoappTests/Pods-wdiodemoapp-wdiodemoappTests-resources.sh\"\n";
354 | showEnvVarsInLog = 0;
355 | };
356 | 7983DC114F19245121DDB2D2 /* [CP] Embed Pods Frameworks */ = {
357 | isa = PBXShellScriptBuildPhase;
358 | buildActionMask = 2147483647;
359 | files = (
360 | );
361 | inputFileListPaths = (
362 | "${PODS_ROOT}/Target Support Files/Pods-wdiodemoapp-wdiodemoappTests/Pods-wdiodemoapp-wdiodemoappTests-frameworks-${CONFIGURATION}-input-files.xcfilelist",
363 | );
364 | name = "[CP] Embed Pods Frameworks";
365 | outputFileListPaths = (
366 | "${PODS_ROOT}/Target Support Files/Pods-wdiodemoapp-wdiodemoappTests/Pods-wdiodemoapp-wdiodemoappTests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
367 | );
368 | runOnlyForDeploymentPostprocessing = 0;
369 | shellPath = /bin/sh;
370 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-wdiodemoapp-wdiodemoappTests/Pods-wdiodemoapp-wdiodemoappTests-frameworks.sh\"\n";
371 | showEnvVarsInLog = 0;
372 | };
373 | 916D8445876CDD9226BE7078 /* [CP] Embed Pods Frameworks */ = {
374 | isa = PBXShellScriptBuildPhase;
375 | buildActionMask = 2147483647;
376 | files = (
377 | );
378 | inputFileListPaths = (
379 | "${PODS_ROOT}/Target Support Files/Pods-wdiodemoapp/Pods-wdiodemoapp-frameworks-${CONFIGURATION}-input-files.xcfilelist",
380 | );
381 | name = "[CP] Embed Pods Frameworks";
382 | outputFileListPaths = (
383 | "${PODS_ROOT}/Target Support Files/Pods-wdiodemoapp/Pods-wdiodemoapp-frameworks-${CONFIGURATION}-output-files.xcfilelist",
384 | );
385 | runOnlyForDeploymentPostprocessing = 0;
386 | shellPath = /bin/sh;
387 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-wdiodemoapp/Pods-wdiodemoapp-frameworks.sh\"\n";
388 | showEnvVarsInLog = 0;
389 | };
390 | B0F225A2A1D795AC9364D4A1 /* [CP] Copy Pods Resources */ = {
391 | isa = PBXShellScriptBuildPhase;
392 | buildActionMask = 2147483647;
393 | files = (
394 | );
395 | inputFileListPaths = (
396 | "${PODS_ROOT}/Target Support Files/Pods-wdiodemoapp/Pods-wdiodemoapp-resources-${CONFIGURATION}-input-files.xcfilelist",
397 | );
398 | name = "[CP] Copy Pods Resources";
399 | outputFileListPaths = (
400 | "${PODS_ROOT}/Target Support Files/Pods-wdiodemoapp/Pods-wdiodemoapp-resources-${CONFIGURATION}-output-files.xcfilelist",
401 | );
402 | runOnlyForDeploymentPostprocessing = 0;
403 | shellPath = /bin/sh;
404 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-wdiodemoapp/Pods-wdiodemoapp-resources.sh\"\n";
405 | showEnvVarsInLog = 0;
406 | };
407 | C48BD2FE476FB58A7F908727 /* [Expo] Configure project */ = {
408 | isa = PBXShellScriptBuildPhase;
409 | alwaysOutOfDate = 1;
410 | buildActionMask = 2147483647;
411 | files = (
412 | );
413 | inputFileListPaths = (
414 | );
415 | inputPaths = (
416 | );
417 | name = "[Expo] Configure project";
418 | outputFileListPaths = (
419 | );
420 | outputPaths = (
421 | );
422 | runOnlyForDeploymentPostprocessing = 0;
423 | shellPath = /bin/sh;
424 | shellScript = "# This script configures Expo modules and generates the modules provider file.\nbash -l -c \"./Pods/Target\\ Support\\ Files/Pods-wdiodemoapp-wdiodemoappTests/expo-configure-project.sh\"\n";
425 | };
426 | C91A6693AD82ACBB515F9253 /* [CP] Check Pods Manifest.lock */ = {
427 | isa = PBXShellScriptBuildPhase;
428 | buildActionMask = 2147483647;
429 | files = (
430 | );
431 | inputFileListPaths = (
432 | );
433 | inputPaths = (
434 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
435 | "${PODS_ROOT}/Manifest.lock",
436 | );
437 | name = "[CP] Check Pods Manifest.lock";
438 | outputFileListPaths = (
439 | );
440 | outputPaths = (
441 | "$(DERIVED_FILE_DIR)/Pods-wdiodemoapp-wdiodemoappTests-checkManifestLockResult.txt",
442 | );
443 | runOnlyForDeploymentPostprocessing = 0;
444 | shellPath = /bin/sh;
445 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
446 | showEnvVarsInLog = 0;
447 | };
448 | E1A3D16B8054AE52DD3BE26C /* [CP] Check Pods Manifest.lock */ = {
449 | isa = PBXShellScriptBuildPhase;
450 | buildActionMask = 2147483647;
451 | files = (
452 | );
453 | inputFileListPaths = (
454 | );
455 | inputPaths = (
456 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
457 | "${PODS_ROOT}/Manifest.lock",
458 | );
459 | name = "[CP] Check Pods Manifest.lock";
460 | outputFileListPaths = (
461 | );
462 | outputPaths = (
463 | "$(DERIVED_FILE_DIR)/Pods-wdiodemoapp-checkManifestLockResult.txt",
464 | );
465 | runOnlyForDeploymentPostprocessing = 0;
466 | shellPath = /bin/sh;
467 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
468 | showEnvVarsInLog = 0;
469 | };
470 | /* End PBXShellScriptBuildPhase section */
471 |
472 | /* Begin PBXSourcesBuildPhase section */
473 | 00E356EA1AD99517003FC87E /* Sources */ = {
474 | isa = PBXSourcesBuildPhase;
475 | buildActionMask = 2147483647;
476 | files = (
477 | 00E356F31AD99517003FC87E /* wdiodemoappTests.m in Sources */,
478 | 58AC821722C8E5AAF95135DD /* ExpoModulesProvider.swift in Sources */,
479 | );
480 | runOnlyForDeploymentPostprocessing = 0;
481 | };
482 | 13B07F871A680F5B00A75B9A /* Sources */ = {
483 | isa = PBXSourcesBuildPhase;
484 | buildActionMask = 2147483647;
485 | files = (
486 | 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */,
487 | 13B07FC11A68108700A75B9A /* main.m in Sources */,
488 | D58558CCE85696350949AABD /* ExpoModulesProvider.swift in Sources */,
489 | );
490 | runOnlyForDeploymentPostprocessing = 0;
491 | };
492 | /* End PBXSourcesBuildPhase section */
493 |
494 | /* Begin PBXTargetDependency section */
495 | 00E356F51AD99517003FC87E /* PBXTargetDependency */ = {
496 | isa = PBXTargetDependency;
497 | target = 13B07F861A680F5B00A75B9A /* wdiodemoapp */;
498 | targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */;
499 | };
500 | /* End PBXTargetDependency section */
501 |
502 | /* Begin XCBuildConfiguration section */
503 | 00E356F61AD99517003FC87E /* Debug */ = {
504 | isa = XCBuildConfiguration;
505 | baseConfigurationReference = B098E6C9A70C7148138F766F /* Pods-wdiodemoapp-wdiodemoappTests.debug.xcconfig */;
506 | buildSettings = {
507 | BUNDLE_LOADER = "$(TEST_HOST)";
508 | GCC_PREPROCESSOR_DEFINITIONS = (
509 | "DEBUG=1",
510 | "$(inherited)",
511 | );
512 | INFOPLIST_FILE = wdiodemoappTests/Info.plist;
513 | IPHONEOS_DEPLOYMENT_TARGET = 13.4;
514 | LD_RUNPATH_SEARCH_PATHS = (
515 | "$(inherited)",
516 | "@executable_path/Frameworks",
517 | "@loader_path/Frameworks",
518 | );
519 | OTHER_LDFLAGS = (
520 | "-ObjC",
521 | "-lc++",
522 | "$(inherited)",
523 | );
524 | OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
525 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
526 | PRODUCT_NAME = "$(TARGET_NAME)";
527 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/wdiodemoapp.app/wdiodemoapp";
528 | };
529 | name = Debug;
530 | };
531 | 00E356F71AD99517003FC87E /* Release */ = {
532 | isa = XCBuildConfiguration;
533 | baseConfigurationReference = 7C0C6C004693AFA68A120E17 /* Pods-wdiodemoapp-wdiodemoappTests.release.xcconfig */;
534 | buildSettings = {
535 | BUNDLE_LOADER = "$(TEST_HOST)";
536 | COPY_PHASE_STRIP = NO;
537 | INFOPLIST_FILE = wdiodemoappTests/Info.plist;
538 | IPHONEOS_DEPLOYMENT_TARGET = 13.4;
539 | LD_RUNPATH_SEARCH_PATHS = (
540 | "$(inherited)",
541 | "@executable_path/Frameworks",
542 | "@loader_path/Frameworks",
543 | );
544 | OTHER_LDFLAGS = (
545 | "-ObjC",
546 | "-lc++",
547 | "$(inherited)",
548 | );
549 | OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
550 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
551 | PRODUCT_NAME = "$(TARGET_NAME)";
552 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/wdiodemoapp.app/wdiodemoapp";
553 | };
554 | name = Release;
555 | };
556 | 13B07F941A680F5B00A75B9A /* Debug */ = {
557 | isa = XCBuildConfiguration;
558 | baseConfigurationReference = 25BA9D4427943074799979B9 /* Pods-wdiodemoapp.debug.xcconfig */;
559 | buildSettings = {
560 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
561 | CLANG_ENABLE_MODULES = YES;
562 | CURRENT_PROJECT_VERSION = 18;
563 | ENABLE_BITCODE = NO;
564 | INFOPLIST_FILE = wdiodemoapp/Info.plist;
565 | LD_RUNPATH_SEARCH_PATHS = (
566 | "$(inherited)",
567 | "@executable_path/Frameworks",
568 | );
569 | MARKETING_VERSION = 1.0;
570 | OTHER_LDFLAGS = (
571 | "$(inherited)",
572 | "-ObjC",
573 | "-lc++",
574 | );
575 | OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
576 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
577 | PRODUCT_NAME = wdiodemoapp;
578 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
579 | SWIFT_VERSION = 5.0;
580 | VERSIONING_SYSTEM = "apple-generic";
581 | };
582 | name = Debug;
583 | };
584 | 13B07F951A680F5B00A75B9A /* Release */ = {
585 | isa = XCBuildConfiguration;
586 | baseConfigurationReference = 53094DCAE92584D148E207E3 /* Pods-wdiodemoapp.release.xcconfig */;
587 | buildSettings = {
588 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
589 | CLANG_ENABLE_MODULES = YES;
590 | CURRENT_PROJECT_VERSION = 18;
591 | INFOPLIST_FILE = wdiodemoapp/Info.plist;
592 | LD_RUNPATH_SEARCH_PATHS = (
593 | "$(inherited)",
594 | "@executable_path/Frameworks",
595 | );
596 | MARKETING_VERSION = 1.0;
597 | OTHER_LDFLAGS = (
598 | "$(inherited)",
599 | "-ObjC",
600 | "-lc++",
601 | );
602 | OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
603 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
604 | PRODUCT_NAME = wdiodemoapp;
605 | SWIFT_VERSION = 5.0;
606 | VERSIONING_SYSTEM = "apple-generic";
607 | };
608 | name = Release;
609 | };
610 | 83CBBA201A601CBA00E9B192 /* Debug */ = {
611 | isa = XCBuildConfiguration;
612 | buildSettings = {
613 | ALWAYS_SEARCH_USER_PATHS = NO;
614 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
615 | CLANG_CXX_LANGUAGE_STANDARD = "c++20";
616 | CLANG_CXX_LIBRARY = "libc++";
617 | CLANG_ENABLE_MODULES = YES;
618 | CLANG_ENABLE_OBJC_ARC = YES;
619 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
620 | CLANG_WARN_BOOL_CONVERSION = YES;
621 | CLANG_WARN_COMMA = YES;
622 | CLANG_WARN_CONSTANT_CONVERSION = YES;
623 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
624 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
625 | CLANG_WARN_EMPTY_BODY = YES;
626 | CLANG_WARN_ENUM_CONVERSION = YES;
627 | CLANG_WARN_INFINITE_RECURSION = YES;
628 | CLANG_WARN_INT_CONVERSION = YES;
629 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
630 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
631 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
632 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
633 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
634 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
635 | CLANG_WARN_STRICT_PROTOTYPES = YES;
636 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
637 | CLANG_WARN_UNREACHABLE_CODE = YES;
638 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
639 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
640 | COPY_PHASE_STRIP = NO;
641 | ENABLE_STRICT_OBJC_MSGSEND = YES;
642 | ENABLE_TESTABILITY = YES;
643 | "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
644 | GCC_C_LANGUAGE_STANDARD = gnu99;
645 | GCC_DYNAMIC_NO_PIC = NO;
646 | GCC_NO_COMMON_BLOCKS = YES;
647 | GCC_OPTIMIZATION_LEVEL = 0;
648 | GCC_PREPROCESSOR_DEFINITIONS = (
649 | "DEBUG=1",
650 | "$(inherited)",
651 | );
652 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
653 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
654 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
655 | GCC_WARN_UNDECLARED_SELECTOR = YES;
656 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
657 | GCC_WARN_UNUSED_FUNCTION = YES;
658 | GCC_WARN_UNUSED_VARIABLE = YES;
659 | IPHONEOS_DEPLOYMENT_TARGET = 13.4;
660 | LD_RUNPATH_SEARCH_PATHS = (
661 | /usr/lib/swift,
662 | "$(inherited)",
663 | );
664 | LIBRARY_SEARCH_PATHS = (
665 | "\"$(SDKROOT)/usr/lib/swift\"",
666 | "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
667 | "\"$(inherited)\"",
668 | );
669 | MTL_ENABLE_DEBUG_INFO = YES;
670 | ONLY_ACTIVE_ARCH = YES;
671 | OTHER_CFLAGS = "$(inherited)";
672 | OTHER_CPLUSPLUSFLAGS = (
673 | "$(OTHER_CFLAGS)",
674 | "-DFOLLY_NO_CONFIG",
675 | "-DFOLLY_MOBILE=1",
676 | "-DFOLLY_USE_LIBCPP=1",
677 | "-DFOLLY_CFG_NO_COROUTINES=1",
678 | );
679 | OTHER_LDFLAGS = (
680 | "$(inherited)",
681 | "-Wl",
682 | "-ld_classic",
683 | );
684 | REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
685 | SDKROOT = iphoneos;
686 | USE_HERMES = true;
687 | };
688 | name = Debug;
689 | };
690 | 83CBBA211A601CBA00E9B192 /* Release */ = {
691 | isa = XCBuildConfiguration;
692 | buildSettings = {
693 | ALWAYS_SEARCH_USER_PATHS = NO;
694 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
695 | CLANG_CXX_LANGUAGE_STANDARD = "c++20";
696 | CLANG_CXX_LIBRARY = "libc++";
697 | CLANG_ENABLE_MODULES = YES;
698 | CLANG_ENABLE_OBJC_ARC = YES;
699 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
700 | CLANG_WARN_BOOL_CONVERSION = YES;
701 | CLANG_WARN_COMMA = YES;
702 | CLANG_WARN_CONSTANT_CONVERSION = YES;
703 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
704 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
705 | CLANG_WARN_EMPTY_BODY = YES;
706 | CLANG_WARN_ENUM_CONVERSION = YES;
707 | CLANG_WARN_INFINITE_RECURSION = YES;
708 | CLANG_WARN_INT_CONVERSION = YES;
709 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
710 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
711 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
712 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
713 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
714 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
715 | CLANG_WARN_STRICT_PROTOTYPES = YES;
716 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
717 | CLANG_WARN_UNREACHABLE_CODE = YES;
718 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
719 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
720 | COPY_PHASE_STRIP = YES;
721 | ENABLE_NS_ASSERTIONS = NO;
722 | ENABLE_STRICT_OBJC_MSGSEND = YES;
723 | "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
724 | GCC_C_LANGUAGE_STANDARD = gnu99;
725 | GCC_NO_COMMON_BLOCKS = YES;
726 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
727 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
728 | GCC_WARN_UNDECLARED_SELECTOR = YES;
729 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
730 | GCC_WARN_UNUSED_FUNCTION = YES;
731 | GCC_WARN_UNUSED_VARIABLE = YES;
732 | IPHONEOS_DEPLOYMENT_TARGET = 13.4;
733 | LD_RUNPATH_SEARCH_PATHS = (
734 | /usr/lib/swift,
735 | "$(inherited)",
736 | );
737 | LIBRARY_SEARCH_PATHS = (
738 | "\"$(SDKROOT)/usr/lib/swift\"",
739 | "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
740 | "\"$(inherited)\"",
741 | );
742 | MTL_ENABLE_DEBUG_INFO = NO;
743 | OTHER_CFLAGS = "$(inherited)";
744 | OTHER_CPLUSPLUSFLAGS = (
745 | "$(OTHER_CFLAGS)",
746 | "-DFOLLY_NO_CONFIG",
747 | "-DFOLLY_MOBILE=1",
748 | "-DFOLLY_USE_LIBCPP=1",
749 | "-DFOLLY_CFG_NO_COROUTINES=1",
750 | );
751 | OTHER_LDFLAGS = (
752 | "$(inherited)",
753 | "-Wl",
754 | "-ld_classic",
755 | );
756 | REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
757 | SDKROOT = iphoneos;
758 | USE_HERMES = true;
759 | VALIDATE_PRODUCT = YES;
760 | };
761 | name = Release;
762 | };
763 | /* End XCBuildConfiguration section */
764 |
765 | /* Begin XCConfigurationList section */
766 | 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "wdiodemoappTests" */ = {
767 | isa = XCConfigurationList;
768 | buildConfigurations = (
769 | 00E356F61AD99517003FC87E /* Debug */,
770 | 00E356F71AD99517003FC87E /* Release */,
771 | );
772 | defaultConfigurationIsVisible = 0;
773 | defaultConfigurationName = Release;
774 | };
775 | 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "wdiodemoapp" */ = {
776 | isa = XCConfigurationList;
777 | buildConfigurations = (
778 | 13B07F941A680F5B00A75B9A /* Debug */,
779 | 13B07F951A680F5B00A75B9A /* Release */,
780 | );
781 | defaultConfigurationIsVisible = 0;
782 | defaultConfigurationName = Release;
783 | };
784 | 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "wdiodemoapp" */ = {
785 | isa = XCConfigurationList;
786 | buildConfigurations = (
787 | 83CBBA201A601CBA00E9B192 /* Debug */,
788 | 83CBBA211A601CBA00E9B192 /* Release */,
789 | );
790 | defaultConfigurationIsVisible = 0;
791 | defaultConfigurationName = Release;
792 | };
793 | /* End XCConfigurationList section */
794 | };
795 | rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;
796 | }
797 |
--------------------------------------------------------------------------------
/ios/wdiodemoapp.xcodeproj/xcshareddata/xcschemes/wdiodemoapp.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
53 |
55 |
61 |
62 |
63 |
64 |
70 |
72 |
78 |
79 |
80 |
81 |
83 |
84 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/ios/wdiodemoapp.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ios/wdiodemoapp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/wdiodemoapp/AppDelegate.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import
4 |
5 | @interface AppDelegate : EXAppDelegateWrapper
6 |
7 | @end
8 |
--------------------------------------------------------------------------------
/ios/wdiodemoapp/AppDelegate.mm:
--------------------------------------------------------------------------------
1 | #import "AppDelegate.h"
2 | #import "RNBootSplash.h"
3 |
4 | #import
5 |
6 | // For Deep Linking
7 | #import
8 |
9 | @implementation AppDelegate
10 |
11 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
12 | {
13 | self.moduleName = @"wdiodemoapp";
14 | // You can add your custom initial props in the dictionary below.
15 | // They will be passed down to the ViewController used by React Native.
16 | self.initialProps = @{};
17 |
18 | return [super application:application didFinishLaunchingWithOptions:launchOptions];
19 | }
20 |
21 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
22 | {
23 | return [self getBundleURL];
24 | }
25 |
26 | - (NSURL *)getBundleURL
27 | {
28 | #if DEBUG
29 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
30 | #else
31 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
32 | #endif
33 | }
34 |
35 | - (UIView *)createRootViewWithBridge:(RCTBridge *)bridge
36 | moduleName:(NSString *)moduleName
37 | initProps:(NSDictionary *)initProps {
38 | UIView *rootView = [super createRootViewWithBridge:bridge
39 | moduleName:moduleName
40 | initProps:initProps];
41 |
42 | [RNBootSplash initWithStoryboard:@"BootSplash" rootView:rootView];
43 |
44 | return rootView;
45 | }
46 | // For Deep Linking
47 | - (BOOL)application:(UIApplication *)application
48 | openURL:(NSURL *)url
49 | options:(NSDictionary *)options
50 | {
51 | return [RCTLinkingManager application:application openURL:url options:options];
52 | }
53 |
54 | @end
55 |
--------------------------------------------------------------------------------
/ios/wdiodemoapp/BootSplash.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/ios/wdiodemoapp/Images.xcassets/AppIcon.appiconset/1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/ios/wdiodemoapp/Images.xcassets/AppIcon.appiconset/1024.png
--------------------------------------------------------------------------------
/ios/wdiodemoapp/Images.xcassets/AppIcon.appiconset/114.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/ios/wdiodemoapp/Images.xcassets/AppIcon.appiconset/114.png
--------------------------------------------------------------------------------
/ios/wdiodemoapp/Images.xcassets/AppIcon.appiconset/120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/ios/wdiodemoapp/Images.xcassets/AppIcon.appiconset/120.png
--------------------------------------------------------------------------------
/ios/wdiodemoapp/Images.xcassets/AppIcon.appiconset/180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/ios/wdiodemoapp/Images.xcassets/AppIcon.appiconset/180.png
--------------------------------------------------------------------------------
/ios/wdiodemoapp/Images.xcassets/AppIcon.appiconset/29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/ios/wdiodemoapp/Images.xcassets/AppIcon.appiconset/29.png
--------------------------------------------------------------------------------
/ios/wdiodemoapp/Images.xcassets/AppIcon.appiconset/40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/ios/wdiodemoapp/Images.xcassets/AppIcon.appiconset/40.png
--------------------------------------------------------------------------------
/ios/wdiodemoapp/Images.xcassets/AppIcon.appiconset/57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/ios/wdiodemoapp/Images.xcassets/AppIcon.appiconset/57.png
--------------------------------------------------------------------------------
/ios/wdiodemoapp/Images.xcassets/AppIcon.appiconset/58.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/ios/wdiodemoapp/Images.xcassets/AppIcon.appiconset/58.png
--------------------------------------------------------------------------------
/ios/wdiodemoapp/Images.xcassets/AppIcon.appiconset/60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/ios/wdiodemoapp/Images.xcassets/AppIcon.appiconset/60.png
--------------------------------------------------------------------------------
/ios/wdiodemoapp/Images.xcassets/AppIcon.appiconset/80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/ios/wdiodemoapp/Images.xcassets/AppIcon.appiconset/80.png
--------------------------------------------------------------------------------
/ios/wdiodemoapp/Images.xcassets/AppIcon.appiconset/87.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/ios/wdiodemoapp/Images.xcassets/AppIcon.appiconset/87.png
--------------------------------------------------------------------------------
/ios/wdiodemoapp/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "40.png",
5 | "idiom" : "iphone",
6 | "scale" : "2x",
7 | "size" : "20x20"
8 | },
9 | {
10 | "filename" : "60.png",
11 | "idiom" : "iphone",
12 | "scale" : "3x",
13 | "size" : "20x20"
14 | },
15 | {
16 | "filename" : "29.png",
17 | "idiom" : "iphone",
18 | "scale" : "1x",
19 | "size" : "29x29"
20 | },
21 | {
22 | "filename" : "58.png",
23 | "idiom" : "iphone",
24 | "scale" : "2x",
25 | "size" : "29x29"
26 | },
27 | {
28 | "filename" : "87.png",
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "29x29"
32 | },
33 | {
34 | "filename" : "80.png",
35 | "idiom" : "iphone",
36 | "scale" : "2x",
37 | "size" : "40x40"
38 | },
39 | {
40 | "filename" : "120.png",
41 | "idiom" : "iphone",
42 | "scale" : "3x",
43 | "size" : "40x40"
44 | },
45 | {
46 | "filename" : "57.png",
47 | "idiom" : "iphone",
48 | "scale" : "1x",
49 | "size" : "57x57"
50 | },
51 | {
52 | "filename" : "114.png",
53 | "idiom" : "iphone",
54 | "scale" : "2x",
55 | "size" : "57x57"
56 | },
57 | {
58 | "filename" : "120.png",
59 | "idiom" : "iphone",
60 | "scale" : "2x",
61 | "size" : "60x60"
62 | },
63 | {
64 | "filename" : "180.png",
65 | "idiom" : "iphone",
66 | "scale" : "3x",
67 | "size" : "60x60"
68 | },
69 | {
70 | "filename" : "1024.png",
71 | "idiom" : "ios-marketing",
72 | "scale" : "1x",
73 | "size" : "1024x1024"
74 | }
75 | ],
76 | "info" : {
77 | "author" : "xcode",
78 | "version" : 1
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/ios/wdiodemoapp/Images.xcassets/AppIcon1.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "2x",
6 | "size" : "20x20"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "3x",
11 | "size" : "20x20"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "29x29"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "3x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "40x40"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "40x40"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "scale" : "2x",
36 | "size" : "60x60"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "scale" : "3x",
41 | "size" : "60x60"
42 | },
43 | {
44 | "idiom" : "ios-marketing",
45 | "scale" : "1x",
46 | "size" : "1024x1024"
47 | }
48 | ],
49 | "info" : {
50 | "author" : "xcode",
51 | "version" : 1
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/ios/wdiodemoapp/Images.xcassets/BootSplashLogo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images": [
3 | {
4 | "idiom": "universal",
5 | "filename": "bootsplash_logo.png",
6 | "scale": "1x"
7 | },
8 | {
9 | "idiom": "universal",
10 | "filename": "bootsplash_logo@2x.png",
11 | "scale": "2x"
12 | },
13 | {
14 | "idiom": "universal",
15 | "filename": "bootsplash_logo@3x.png",
16 | "scale": "3x"
17 | }
18 | ],
19 | "info": {
20 | "author": "xcode",
21 | "version": 1
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ios/wdiodemoapp/Images.xcassets/BootSplashLogo.imageset/bootsplash_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/ios/wdiodemoapp/Images.xcassets/BootSplashLogo.imageset/bootsplash_logo.png
--------------------------------------------------------------------------------
/ios/wdiodemoapp/Images.xcassets/BootSplashLogo.imageset/bootsplash_logo@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/ios/wdiodemoapp/Images.xcassets/BootSplashLogo.imageset/bootsplash_logo@2x.png
--------------------------------------------------------------------------------
/ios/wdiodemoapp/Images.xcassets/BootSplashLogo.imageset/bootsplash_logo@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/ios/wdiodemoapp/Images.xcassets/BootSplashLogo.imageset/bootsplash_logo@3x.png
--------------------------------------------------------------------------------
/ios/wdiodemoapp/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ios/wdiodemoapp/Images.xcassets/webdriverio.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "webdriverio.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "webdriverio@2x.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "filename" : "webdriverio@3x.png",
15 | "idiom" : "universal",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "author" : "xcode",
21 | "version" : 1
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ios/wdiodemoapp/Images.xcassets/webdriverio.imageset/webdriverio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/ios/wdiodemoapp/Images.xcassets/webdriverio.imageset/webdriverio.png
--------------------------------------------------------------------------------
/ios/wdiodemoapp/Images.xcassets/webdriverio.imageset/webdriverio@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/ios/wdiodemoapp/Images.xcassets/webdriverio.imageset/webdriverio@2x.png
--------------------------------------------------------------------------------
/ios/wdiodemoapp/Images.xcassets/webdriverio.imageset/webdriverio@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/ios/wdiodemoapp/Images.xcassets/webdriverio.imageset/webdriverio@3x.png
--------------------------------------------------------------------------------
/ios/wdiodemoapp/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | wdiodemoapp
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0.8
21 | CFBundleSignature
22 | ????
23 | CFBundleURLTypes
24 |
25 |
26 | CFBundleURLSchemes
27 |
28 | wdio
29 |
30 |
31 |
32 | CFBundleVersion
33 | 18
34 | LSRequiresIPhoneOS
35 |
36 | NSAppTransportSecurity
37 |
38 | NSAllowsArbitraryLoads
39 |
40 | NSAllowsLocalNetworking
41 |
42 |
43 | NSFaceIDUsageDescription
44 | $(PRODUCT_NAME) requires FaceID access to allows you quick and secure access.
45 | NSLocationWhenInUseUsageDescription
46 |
47 | UIAppFonts
48 |
49 | MaterialIcons.ttf
50 | MaterialCommunityIcons.ttf
51 |
52 | UILaunchStoryboardName
53 |
54 | UIRequiredDeviceCapabilities
55 |
56 | armv7
57 |
58 | UISupportedInterfaceOrientations
59 |
60 | UIInterfaceOrientationPortrait
61 | UIInterfaceOrientationLandscapeLeft
62 | UIInterfaceOrientationLandscapeRight
63 |
64 | UIViewControllerBasedStatusBarAppearance
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/ios/wdiodemoapp/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/ios/wdiodemoapp/main.m:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | #import "AppDelegate.h"
4 |
5 | int main(int argc, char *argv[])
6 | {
7 | @autoreleasepool {
8 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/ios/wdiodemoappTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0.8
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 18
23 |
24 |
25 |
--------------------------------------------------------------------------------
/ios/wdiodemoappTests/wdiodemoappTests.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | #import
5 | #import
6 |
7 | #define TIMEOUT_SECONDS 600
8 | #define TEXT_TO_LOOK_FOR @"Welcome to React"
9 |
10 | @interface wdiodemoappTests : XCTestCase
11 |
12 | @end
13 |
14 | @implementation wdiodemoappTests
15 |
16 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL (^)(UIView *view))test
17 | {
18 | if (test(view)) {
19 | return YES;
20 | }
21 | for (UIView *subview in [view subviews]) {
22 | if ([self findSubviewInView:subview matching:test]) {
23 | return YES;
24 | }
25 | }
26 | return NO;
27 | }
28 |
29 | - (void)testRendersWelcomeScreen
30 | {
31 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController];
32 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
33 | BOOL foundElement = NO;
34 |
35 | __block NSString *redboxError = nil;
36 | #ifdef DEBUG
37 | RCTSetLogFunction(
38 | ^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
39 | if (level >= RCTLogLevelError) {
40 | redboxError = message;
41 | }
42 | });
43 | #endif
44 |
45 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
46 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
47 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
48 |
49 | foundElement = [self findSubviewInView:vc.view
50 | matching:^BOOL(UIView *view) {
51 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
52 | return YES;
53 | }
54 | return NO;
55 | }];
56 | }
57 |
58 | #ifdef DEBUG
59 | RCTSetLogFunction(RCTDefaultLogFunction);
60 | #endif
61 |
62 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
63 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
64 | }
65 |
66 | @end
67 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: 'react-native',
3 | };
4 |
--------------------------------------------------------------------------------
/metro.config.js:
--------------------------------------------------------------------------------
1 | const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
2 |
3 | /**
4 | * Metro configuration
5 | * https://facebook.github.io/metro/docs/configuration
6 | *
7 | * @type {import('metro-config').MetroConfig}
8 | */
9 | const config = {};
10 |
11 | module.exports = mergeConfig(getDefaultConfig(__dirname), config);
12 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wdiodemoapp",
3 | "version": "1.0.8",
4 | "private": true,
5 | "scripts": {
6 | "android.clean": "cd android && ./gradlew clean && cd .. ",
7 | "android.dev": "npm run android.clean && npm run build.version.android && react-native run-android",
8 | "android.release": "cd android && ./gradlew clean && ./gradlew assembleRelease",
9 | "ios.dev": "npm run ios.pods && npm run build.version.ios && react-native run-ios",
10 | "ios.pods": "cd ios && pod install && cd ..",
11 | "ios.release.sim.build": "npm run ios.pods && react-native run-ios --mode=Release",
12 | "lint": "eslint .",
13 | "start": "react-native start",
14 | "test": "jest",
15 | "build.version.android": "react-native-version -A -b --target android",
16 | "build.version.ios": "react-native-version -A -b -L --target ios",
17 | "build.versions": "react-native-version -A -L",
18 | "postinstall": "patch-package"
19 | },
20 | "dependencies": {
21 | "@react-native-picker/picker": "^2.6.1",
22 | "@react-navigation/bottom-tabs": "^6.5.11",
23 | "@react-navigation/material-bottom-tabs": "^6.2.19",
24 | "@react-navigation/native": "^6.1.9",
25 | "expo": ">=50.0.0-0 <51.0.0",
26 | "expo-local-authentication": "^13.6.0",
27 | "react": "18.2.0",
28 | "react-native": "0.73.1",
29 | "react-native-biometrics": "^3.0.1",
30 | "react-native-bootsplash": "^5.2.0",
31 | "react-native-confetti-cannon": "^1.5.2",
32 | "react-native-device-info": "^10.12.0",
33 | "react-native-elements": "^3.4.3",
34 | "react-native-gesture-handler": "^2.14.0",
35 | "react-native-paper": "^5.11.4",
36 | "react-native-picker-select": "^9.0.0",
37 | "react-native-reanimated": "^3.6.1",
38 | "react-native-reanimated-carousel": "^3.5.1",
39 | "react-native-safe-area-context": "^4.8.2",
40 | "react-native-screens": "^3.29.0",
41 | "react-native-vector-icons": "^10.0.3",
42 | "react-native-webview": "^13.6.3"
43 | },
44 | "devDependencies": {
45 | "@babel/core": "^7.20.0",
46 | "@babel/preset-env": "^7.20.0",
47 | "@babel/runtime": "^7.20.0",
48 | "@react-native/babel-preset": "^0.73.18",
49 | "@react-native/eslint-config": "^0.73.1",
50 | "@react-native/metro-config": "^0.73.2",
51 | "@react-native/typescript-config": "^0.73.1",
52 | "@types/babel__core": "^7.20.5",
53 | "@types/babel__preset-env": "^7.9.6",
54 | "@types/eslint": "^8.56.0",
55 | "@types/prettier": "3.0.0",
56 | "@types/react": "^18.2.6",
57 | "@types/react-native-vector-icons": "^6.4.18",
58 | "@types/react-test-renderer": "^18.0.0",
59 | "babel-jest": "^29.6.3",
60 | "eslint": "^8.19.0",
61 | "jest": "^29.6.3",
62 | "patch-package": "^8.0.0",
63 | "postinstall-postinstall": "^2.1.0",
64 | "prettier": "2.8.8",
65 | "react-native-version": "^4.0.0",
66 | "react-test-renderer": "18.2.0",
67 | "typescript": "5.0.4"
68 | },
69 | "engines": {
70 | "node": ">=18"
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/patches/react-native+0.73.1.patch:
--------------------------------------------------------------------------------
1 | diff --git a/node_modules/react-native/third-party-podspecs/boost.podspec b/node_modules/react-native/third-party-podspecs/boost.podspec
2 | index 3950fce..8cd4a8a 100644
3 | --- a/node_modules/react-native/third-party-podspecs/boost.podspec
4 | +++ b/node_modules/react-native/third-party-podspecs/boost.podspec
5 | @@ -10,7 +10,8 @@ Pod::Spec.new do |spec|
6 | spec.homepage = 'http://www.boost.org'
7 | spec.summary = 'Boost provides free peer-reviewed portable C++ source libraries.'
8 | spec.authors = 'Rene Rivera'
9 | - spec.source = { :http => 'https://boostorg.jfrog.io/artifactory/main/release/1.83.0/source/boost_1_83_0.tar.bz2',
10 | + # Patched due to issue https://github.com/boostorg/boost/issues/843
11 | + spec.source = { :http => 'https://sourceforge.net/projects/boost/files/boost/1.83.0/boost_1_83_0.tar.bz2',
12 | :sha256 => '6478edfe2f3305127cffe8caf73ea0176c53769f4bf1585be237eb30798c3b8e' }
13 |
14 | # Pinning to the same version as React.podspec.
15 |
--------------------------------------------------------------------------------
/react-native.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | dependencies: {
3 | 'react-native-vector-icons': {
4 | platforms: {
5 | ios: null,
6 | },
7 | },
8 | },
9 | };
--------------------------------------------------------------------------------
/src/App.tsx:
--------------------------------------------------------------------------------
1 | /* eslint-disable react/no-unstable-nested-components */
2 | import React from 'react';
3 | import {Text} from 'react-native';
4 | import {GestureHandlerRootView} from 'react-native-gesture-handler';
5 | import {NavigationContainer} from '@react-navigation/native';
6 | import {SafeAreaProvider} from 'react-native-safe-area-context';
7 | import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
8 | import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
9 | import RNBootSplash from 'react-native-bootsplash';
10 | import WdioStatusBar from './components/StatusBar';
11 | import DragScreen from './screens/Drag';
12 | import FormsScreen from './screens/Forms';
13 | import HomeScreen from './screens/Home';
14 | import LoginScreen from './screens/Login';
15 | import SwipeScreen from './screens/Swipe';
16 | import WebviewScreen from './screens/WebView';
17 | import Colors from './config/Colors';
18 | import {HAS_IOS_NOTCH} from './config/Constants';
19 | const Tab = createBottomTabNavigator();
20 | const linking = {
21 | prefixes: ['wdio://'],
22 | config: {
23 | screens: {
24 | Home: 'home',
25 | Webview: 'webview',
26 | Login: 'login',
27 | Forms: 'forms',
28 | Swipe: 'swipe',
29 | Drag: 'drag',
30 | },
31 | },
32 | };
33 | type Color = {color: string};
34 | const App = () => {
35 | return (
36 |
37 |
38 |
39 | Loading...}
42 | onReady={() => RNBootSplash.hide({fade: true})}>
43 |
65 | (
72 |
73 | ),
74 | }}
75 | />
76 | (
83 |
84 | ),
85 | }}
86 | />
87 | (
94 |
95 | ),
96 | }}
97 | />
98 | (
105 |
106 | ),
107 | }}
108 | />
109 | (
116 |
117 | ),
118 | }}
119 | />
120 | (
127 |
128 | ),
129 | }}
130 | />
131 |
132 |
133 |
134 |
135 | );
136 | };
137 |
138 | export default App;
139 |
--------------------------------------------------------------------------------
/src/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wdiodemoapp",
3 | "displayName": "wdiodemoapp"
4 | }
5 |
--------------------------------------------------------------------------------
/src/assets/images/wdio-c1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/src/assets/images/wdio-c1.png
--------------------------------------------------------------------------------
/src/assets/images/wdio-c2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/src/assets/images/wdio-c2.png
--------------------------------------------------------------------------------
/src/assets/images/wdio-c3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/src/assets/images/wdio-c3.png
--------------------------------------------------------------------------------
/src/assets/images/wdio-l1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/src/assets/images/wdio-l1.png
--------------------------------------------------------------------------------
/src/assets/images/wdio-l2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/src/assets/images/wdio-l2.png
--------------------------------------------------------------------------------
/src/assets/images/wdio-l3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/src/assets/images/wdio-l3.png
--------------------------------------------------------------------------------
/src/assets/images/wdio-r1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/src/assets/images/wdio-r1.png
--------------------------------------------------------------------------------
/src/assets/images/wdio-r2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/src/assets/images/wdio-r2.png
--------------------------------------------------------------------------------
/src/assets/images/wdio-r3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/src/assets/images/wdio-r3.png
--------------------------------------------------------------------------------
/src/assets/io.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/src/assets/io.png
--------------------------------------------------------------------------------
/src/assets/webdriverio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webdriverio/native-demo-app/935d9560ef3f58249859dcff44113995492ba197/src/assets/webdriverio.png
--------------------------------------------------------------------------------
/src/components/BorderText.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {Text, StyleSheet, Platform} from 'react-native';
3 | import Colors from '../config/Colors';
4 |
5 | const BorderText: React.FC<{text: string}> = ({text}) => {
6 | return (
7 |
8 | {text.toUpperCase()}
9 |
10 | );
11 | };
12 |
13 | const styles = StyleSheet.create({
14 | headerBorder: {
15 | backgroundColor: Colors.black,
16 | borderColor: Colors.orange,
17 | borderWidth: 5,
18 | ...Platform.select({
19 | ios: {
20 | paddingBottom: 9,
21 | },
22 | android: {
23 | paddingBottom: 4,
24 | },
25 | }),
26 | paddingLeft: 13,
27 | paddingRight: 13,
28 | paddingTop: 9,
29 | textAlign: 'center',
30 | },
31 | header: {
32 | color: Colors.orange,
33 | fontSize: 40,
34 | },
35 | });
36 |
37 | export default BorderText;
38 |
--------------------------------------------------------------------------------
/src/components/Button.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | ActivityIndicator,
4 | StyleSheet,
5 | Text,
6 | TouchableOpacity,
7 | View,
8 | } from 'react-native';
9 | import {testProperties} from '../config/TestProperties';
10 | import Colors from '../config/Colors';
11 |
12 | const Button: React.FC<{
13 | backgroundColor?: string;
14 | containerStyle?: object;
15 | disabled?: boolean;
16 | childComponent?: React.ReactNode;
17 | loading?: boolean;
18 | onPress?: () => void;
19 | testID?: string;
20 | text?: string;
21 | textStyle?: object;
22 | }> = ({
23 | backgroundColor = 'transparent',
24 | containerStyle = {},
25 | disabled = false,
26 | childComponent,
27 | loading = false,
28 | onPress = () => {},
29 | testID,
30 | text,
31 | textStyle = {},
32 | }) => {
33 | const buttonTextStyle = [styles.text, textStyle];
34 | if (loading) {
35 | buttonTextStyle.push(styles.textOffset);
36 | }
37 | if (disabled) {
38 | buttonTextStyle.push(styles.disabledText);
39 | }
40 |
41 | return (
42 | (!disabled ? onPress() : null)}
45 | activeOpacity={disabled ? 1 : undefined}
46 | {...testProperties(`button-${testID || text}`, true)}>
47 |
52 | {loading ? (
53 |
54 | ) : (
55 | childComponent || {text}
56 | )}
57 |
58 |
59 | );
60 | };
61 |
62 | const styles = StyleSheet.create({
63 | container: {
64 | minHeight: 40,
65 | },
66 | content: {
67 | flex: 1,
68 | flexDirection: 'row',
69 | paddingHorizontal: 15,
70 | justifyContent: 'center',
71 | alignItems: 'center',
72 | },
73 | disabledContent: {
74 | backgroundColor: Colors.lighter,
75 | },
76 | text: {
77 | textAlign: 'center',
78 | color: Colors.black,
79 | alignSelf: 'center',
80 | },
81 | textOffset: {
82 | marginLeft: 5,
83 | },
84 | disabledText: {
85 | color: Colors.darker,
86 | },
87 | });
88 |
89 | export default Button;
90 |
--------------------------------------------------------------------------------
/src/components/Draggable.tsx:
--------------------------------------------------------------------------------
1 | import React, {MutableRefObject, useMemo, useRef} from 'react';
2 | import {
3 | Animated,
4 | Image,
5 | PanResponder,
6 | PanResponderGestureState,
7 | StyleSheet,
8 | View,
9 | } from 'react-native';
10 | import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
11 | import {testProperties} from '../config/TestProperties';
12 | import Colors from '../config/Colors';
13 |
14 | const Draggable = ({
15 | dropZone,
16 | isDropZone,
17 | resetOpacity,
18 | updateCounter,
19 | setDropZoneValues,
20 | src,
21 | testID,
22 | }: {
23 | dropZone: any;
24 | isDropZone: (arg: PanResponderGestureState) => boolean;
25 | resetOpacity: boolean;
26 | updateCounter: () => void;
27 | setDropZoneValues: (arg: MutableRefObject) => void;
28 | src: number;
29 | testID: string;
30 | }) => {
31 | const pan = useRef(new Animated.ValueXY());
32 | const animatedView = useRef(null);
33 | let opacity = 1;
34 | const setOpacity = (elementOpacity: number) =>
35 | animatedView.current?.setNativeProps({style: {opacity: elementOpacity}});
36 | const panResponder = useMemo(
37 | () =>
38 | PanResponder.create({
39 | onStartShouldSetPanResponder: () => true,
40 | onMoveShouldSetPanResponderCapture: () => true,
41 | onPanResponderGrant: () => {
42 | setDropZoneValues(dropZone);
43 | pan.current.setValue({x: 0, y: 0});
44 | },
45 | onPanResponderMove: Animated.event(
46 | [null, {dx: pan.current.x, dy: pan.current.y}],
47 | {useNativeDriver: false},
48 | ),
49 | onPanResponderRelease: (e, gesture) => {
50 | pan.current.flattenOffset();
51 | if (isDropZone(gesture)) {
52 | // Set opacity to 0 for all matching elements and put element back
53 | setOpacity(0);
54 | pan.current.setValue({x: 0, y: 0});
55 | dropZone.current.setNativeProps({style: {opacity: 0}});
56 | updateCounter();
57 | } else {
58 | Animated.spring(pan.current, {
59 | toValue: {x: 0, y: 0},
60 | useNativeDriver: false,
61 | }).start();
62 | }
63 | },
64 | }),
65 | [dropZone, isDropZone, updateCounter, setDropZoneValues],
66 | );
67 |
68 | if (resetOpacity) {
69 | setOpacity(1);
70 | }
71 |
72 | return (
73 |
74 |
79 |
80 |
85 |
86 |
87 | );
88 | };
89 |
90 | const styles = StyleSheet.create({
91 | dragBox: {
92 | borderWidth: 1,
93 | borderColor: Colors.orange,
94 | borderRadius: 1,
95 | height: 60,
96 | margin: 2,
97 | width: 60,
98 | },
99 | icon: {
100 | position: 'absolute',
101 | top: 0,
102 | left: 0,
103 | },
104 | });
105 |
106 | export default Draggable;
107 |
--------------------------------------------------------------------------------
/src/components/FormComponents.tsx:
--------------------------------------------------------------------------------
1 | import React, {useState} from 'react';
2 | import {
3 | Alert,
4 | StyleSheet,
5 | Switch,
6 | Text,
7 | useColorScheme,
8 | View,
9 | } from 'react-native';
10 | import RNPickerSelect from 'react-native-picker-select';
11 | import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
12 | import {Input} from 'react-native-elements';
13 | import {WINDOW_WIDTH} from '../config/Constants';
14 | import {testProperties} from '../config/TestProperties';
15 | import Button from './Button';
16 | import TitleDivider from './TitleDivider';
17 | import Colors from '../config/Colors';
18 |
19 | const options = [
20 | {
21 | value: '1',
22 | label: 'webdriver.io is awesome',
23 | },
24 | {
25 | value: '2',
26 | label: 'Appium is awesome',
27 | },
28 | {
29 | value: '3',
30 | label: 'This app is awesome',
31 | },
32 | ];
33 | const Chevron: React.FC = () => {
34 | const isDarkMode = useColorScheme() === 'dark';
35 | return (
36 |
41 | );
42 | };
43 | const FormComponents = () => {
44 | const isDarkMode = useColorScheme() === 'dark';
45 | const [isSwitchActive, setIsSwitchActive] = useState(false);
46 | const [inputText, setInputText] = useState('');
47 | const [pickerValue, setPickerValue] = useState('');
48 |
49 | const showAlert = () => {
50 | Alert.alert(
51 | 'This button is',
52 | 'This button is active',
53 | [{text: 'Ask me later'}, {text: 'Cancel'}, {text: 'OK'}],
54 | {cancelable: false},
55 | );
56 | };
57 |
58 | return (
59 |
64 |
65 |
66 |
72 | setInputText(text)}
79 | label="Input field:"
80 | labelStyle={[
81 | styles.inputLabelStyle,
82 | {color: isDarkMode ? Colors.white : Colors.black},
83 | ]}
84 | containerStyle={styles.inputContainerStyle}
85 | inputContainerStyle={styles.inputInnerContainerStyle}
86 | inputStyle={[
87 | styles.inputStyle,
88 | {color: isDarkMode ? Colors.white : Colors.black},
89 | ]}
90 | maxLength={30}
91 | multiline={false}
92 | {...testProperties('text-input')}
93 | />
94 |
99 | You have typed:
100 |
101 |
107 | {inputText}
108 |
109 |
110 |
116 |
121 | Switch:
122 |
123 | setIsSwitchActive(!isSwitchActive)}
126 | style={styles.switch}
127 | trackColor={{false: '#FF5C06', true: '#FF5C06'}}
128 | thumbColor={'#f4f3f4'}
129 | ios_backgroundColor="#f4f3f4"
130 | {...testProperties('switch')}
131 | />
132 |
135 | {`Click to turn the switch ${isSwitchActive ? 'OFF' : 'ON'}`}
136 |
137 |
138 |
139 |
144 | Dropdown:
145 |
146 | setPickerValue(itemValue)}
150 | items={options}
151 | style={{
152 | ...pickerSelectStyles,
153 | inputAndroid: {
154 | color: isDarkMode ? Colors.white : Colors.black,
155 | },
156 | inputIOS: {
157 | color: isDarkMode ? Colors.white : Colors.black,
158 | marginVertical: 10,
159 | },
160 | }}
161 | pickerProps={{...testProperties('Dropdown picker')}}
162 | touchableWrapperProps={{...testProperties('Dropdown', true)}}
163 | // @ts-ignore
164 | Icon={Chevron}
165 | />
166 |
167 |
168 |
173 | Buttons
174 |
175 |
176 |
183 |
189 |
190 |
191 |
192 |
193 | );
194 | };
195 |
196 | const styles = StyleSheet.create({
197 | container: {
198 | flex: 1,
199 | alignItems: 'center',
200 | marginBottom: 20,
201 | },
202 | formComponentsContainer: {
203 | width: WINDOW_WIDTH - 30,
204 | paddingTop: 30,
205 | paddingBottom: 30,
206 | borderRadius: 20,
207 | borderColor: Colors.orange,
208 | borderWidth: 5,
209 | },
210 | formGroup: {
211 | marginHorizontal: 20,
212 | paddingHorizontal: 10,
213 | paddingBottom: 10,
214 | marginBottom: 10,
215 | },
216 | borderContainer: {
217 | borderBottomColor: Colors.orange,
218 | borderBottomWidth: 1,
219 | },
220 | inputContainer: {
221 | marginHorizontal: 20,
222 | paddingHorizontal: 0,
223 | },
224 | labelText: {
225 | fontSize: 16,
226 | fontWeight: 'bold',
227 | },
228 | inputLabelStyle: {
229 | fontWeight: 'bold',
230 | },
231 | inputContainerStyle: {
232 | width: WINDOW_WIDTH - 80,
233 | },
234 | inputInnerContainerStyle: {
235 | borderColor: Colors.orange,
236 | },
237 | inputStyle: {
238 | paddingHorizontal: 10,
239 | fontSize: 14,
240 | },
241 | inputTextLabel: {
242 | paddingLeft: 10,
243 | fontStyle: 'italic',
244 | },
245 | inputText: {
246 | fontSize: 12,
247 | fontWeight: '100',
248 | padding: 10,
249 | height: 35,
250 | borderWidth: 1,
251 | borderColor: Colors.lighter,
252 | marginHorizontal: 10,
253 | marginVertical: 10,
254 | },
255 | switchContainer: {
256 | flex: 1,
257 | alignItems: 'flex-start',
258 | paddingLeft: 10,
259 | },
260 | switch: {
261 | marginTop: 10,
262 | marginBottom: 10,
263 | },
264 | buttonContainer: {
265 | flexDirection: 'row',
266 | justifyContent: 'center',
267 | },
268 | button: {
269 | borderRadius: 5,
270 | height: 50,
271 | width: 125,
272 | backgroundColor: Colors.orange,
273 | borderColor: Colors.orange,
274 | borderWidth: 5,
275 | marginTop: 20,
276 | },
277 | buttonLeft: {
278 | marginLeft: 10,
279 | borderColor: Colors.lighter,
280 | },
281 | buttonText: {
282 | fontSize: 16,
283 | color: Colors.white,
284 | },
285 | });
286 | const pickerSelectStyles = StyleSheet.create({
287 | inputIOS: {
288 | paddingRight: 30, // to ensure the text is never behind the icon
289 | },
290 | inputAndroid: {
291 | paddingRight: 30, // to ensure the text is never behind the icon
292 | },
293 | iconContainer: {
294 | top: 10,
295 | right: 12,
296 | },
297 | });
298 | export default FormComponents;
299 |
--------------------------------------------------------------------------------
/src/components/LoginForm.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Basics used from:
3 | * https://github.com/react-native-training/react-native-elements-app/blob/master/src/views/login/screen3.js
4 | *
5 | * Credits to the React Native Elements team!
6 | */
7 | import React, {useCallback, useEffect, useRef, useState} from 'react';
8 | import {
9 | StyleSheet,
10 | View,
11 | LayoutAnimation,
12 | UIManager,
13 | KeyboardAvoidingView,
14 | Alert,
15 | TextInput,
16 | useColorScheme,
17 | Text,
18 | } from 'react-native';
19 | import {Input} from 'react-native-elements';
20 | import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
21 | import * as LocalAuthentication from 'expo-local-authentication';
22 | import {IS_IOS, WINDOW_WIDTH} from '../config/Constants';
23 | import {testProperties} from '../config/TestProperties';
24 | import Button from './Button';
25 | import TitleDivider from './TitleDivider';
26 | import Colors from '../config/Colors';
27 |
28 | // Enable LayoutAnimation on Android
29 | UIManager.setLayoutAnimationEnabledExperimental &&
30 | UIManager.setLayoutAnimationEnabledExperimental(true);
31 |
32 | type BiometryType =
33 | | 'BIOMETRICS'
34 | | 'FINGERPRINT'
35 | | 'FACIAL_RECOGNITION'
36 | | 'IRIS';
37 | const BIOMETRICS_TYPE: {[key: string]: BiometryType} = {
38 | FINGERPRINT: 'FINGERPRINT',
39 | FACIAL_RECOGNITION: 'FACIAL_RECOGNITION',
40 | IRIS: 'IRIS',
41 | BIOMETRICS: 'BIOMETRICS',
42 | };
43 | const TabSelector: React.FC<{selected: boolean}> = ({selected}) => {
44 | return (
45 |
46 |
47 |
48 | );
49 | };
50 | const LoginForm = () => {
51 | // States
52 | const [email, setEmail] = useState('');
53 | const [password, setPassword] = useState('');
54 | const [passwordConfirmation, setPasswordConfirmation] = useState('');
55 | const [selectedCategory, setSelectedCategory] = useState(0);
56 | const [isLoading, setIsLoading] = useState(false);
57 | const [isEmailValid, setIsEmailValid] = useState(true);
58 | const [isPasswordValid, setIsPasswordValid] = useState(true);
59 | const [isConfirmationValid, setIsConfirmationValid] = useState(true);
60 | const [isBiometricAvailable, setIsBiometricAvailable] = useState(false);
61 | const [biometricsType, setBiometricsType] = useState(
62 | null,
63 | );
64 |
65 | // Constants
66 | const isDarkMode = useColorScheme() === 'dark';
67 | const isLoginPage = selectedCategory === 0;
68 | const isSignUpPage = selectedCategory === 1;
69 | const biometricName =
70 | biometricsType === BIOMETRICS_TYPE.FINGERPRINT
71 | ? 'fingerprint'
72 | : 'face-recognition';
73 |
74 | // Element Refs
75 | interface RNInput extends TextInput {
76 | shake(): void;
77 | focus(): void;
78 | }
79 | const emailEl = useRef(null);
80 | const passwordEl = useRef(null);
81 | const passwordConfirmationEl = useRef(null);
82 |
83 | // Methods
84 | const selectCategory = (category: number) => {
85 | LayoutAnimation.easeInEaseOut();
86 | setSelectedCategory(category);
87 | setIsLoading(false);
88 | };
89 | const validateEmail = (text: string) => {
90 | const re =
91 | /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
92 |
93 | return re.test(text);
94 | };
95 | const validateForm = () => {
96 | // Check email
97 | const validEmail = validateEmail(email);
98 | setIsEmailValid(validEmail);
99 | if (!validEmail) {
100 | emailEl?.current?.shake();
101 | }
102 |
103 | // Check password
104 | const validPassword = password.length >= 8;
105 | setIsPasswordValid(validPassword);
106 | if (!validPassword) {
107 | passwordEl?.current?.shake();
108 | }
109 |
110 | // Check password confirmation
111 | let validPasswordConfirmation: boolean = false;
112 | if (isSignUpPage) {
113 | validPasswordConfirmation =
114 | password === passwordConfirmation && passwordConfirmation.length >= 8;
115 | setIsConfirmationValid(validPasswordConfirmation);
116 | if (validPasswordConfirmation) {
117 | passwordConfirmationEl?.current?.shake();
118 | }
119 | }
120 |
121 | if (
122 | (isLoginPage && validEmail && validPassword) ||
123 | (isSignUpPage && validEmail && validPassword && validPasswordConfirmation)
124 | ) {
125 | setIsLoading(true);
126 | // Simulate an API call
127 | setTimeout(() => {
128 | LayoutAnimation.easeInEaseOut();
129 | setIsLoading(false);
130 | if (isLoginPage) {
131 | Alert.alert('Success', 'You are logged in!', [{text: 'OK'}], {
132 | cancelable: false,
133 | });
134 | } else {
135 | Alert.alert(
136 | 'Signed Up!',
137 | 'You successfully signed up!',
138 | [{text: 'OK'}],
139 | {cancelable: false},
140 | );
141 | }
142 | }, 1500);
143 | }
144 | };
145 | const handleBiometryLogin = useCallback(async () => {
146 | try {
147 | setIsEmailValid(true);
148 | setIsPasswordValid(true);
149 | const sensorType =
150 | IS_IOS && biometricsType === BIOMETRICS_TYPE.FINGERPRINT
151 | ? 'TouchID'
152 | : IS_IOS
153 | ? 'FaceID'
154 | : biometricsType === BIOMETRICS_TYPE.IRIS
155 | ? 'Iris'
156 | : biometricsType === BIOMETRICS_TYPE.FINGERPRINT
157 | ? 'Fingerprint'
158 | : 'Biometrics';
159 | const {success} = await LocalAuthentication.authenticateAsync({
160 | promptMessage: `Login with ${sensorType}`,
161 | disableDeviceFallback: true,
162 | cancelLabel: 'Cancel',
163 | });
164 | if (success) {
165 | Alert.alert(
166 | 'Success',
167 | `You are logged in through ${sensorType}!`,
168 | [{text: 'OK'}],
169 | {
170 | cancelable: false,
171 | },
172 | );
173 | }
174 | } catch (err) {
175 | console.log(err);
176 | }
177 | }, [biometricsType]);
178 | const getBiometricsType = (types: number[]) => {
179 | let type: BiometryType;
180 | switch (types[0]) {
181 | case 1:
182 | type = BIOMETRICS_TYPE.FINGERPRINT;
183 | break;
184 | case 2:
185 | type = BIOMETRICS_TYPE.FACIAL_RECOGNITION;
186 | break;
187 | case 3:
188 | type = BIOMETRICS_TYPE.IRIS;
189 | break;
190 | default:
191 | type = BIOMETRICS_TYPE.BIOMETRICS;
192 | }
193 | setBiometricsType(type);
194 | };
195 |
196 | useEffect(() => {
197 | (async () => {
198 | setIsBiometricAvailable(await LocalAuthentication.isEnrolledAsync());
199 | getBiometricsType(
200 | await LocalAuthentication.supportedAuthenticationTypesAsync(),
201 | );
202 | })();
203 | });
204 |
205 | return (
206 |
207 |
210 |
211 |
212 |
237 |
238 |
239 |
240 |
241 |
246 | }
248 | value={email}
249 | keyboardAppearance="light"
250 | autoFocus={false}
251 | autoCapitalize="none"
252 | autoCorrect={false}
253 | keyboardType="email-address"
254 | returnKeyType="next"
255 | inputStyle={[
256 | styles.inputStyle,
257 | {color: isDarkMode ? Colors.white : Colors.black},
258 | ]}
259 | placeholder={'Email'}
260 | inputContainerStyle={styles.inputContainerStyle}
261 | ref={emailEl}
262 | onSubmitEditing={() => passwordEl?.current?.focus()}
263 | onChangeText={emailText => setEmail(emailText)}
264 | errorMessage={
265 | isEmailValid ? undefined : 'Please enter a valid email address'
266 | }
267 | {...testProperties('input-email')}
268 | />
269 | }
271 | value={password}
272 | keyboardAppearance="light"
273 | autoCapitalize="none"
274 | autoCorrect={false}
275 | secureTextEntry={true}
276 | returnKeyType={isSignUpPage ? 'next' : 'done'}
277 | blurOnSubmit={true}
278 | containerStyle={styles.containerStyle}
279 | inputContainerStyle={styles.inputContainerStyle}
280 | inputStyle={[
281 | styles.inputStyle,
282 | {color: isDarkMode ? Colors.white : Colors.black},
283 | ]}
284 | placeholder={'Password'}
285 | ref={passwordEl}
286 | onSubmitEditing={() =>
287 | isSignUpPage
288 | ? passwordConfirmationEl?.current?.focus()
289 | : validateForm()
290 | }
291 | onChangeText={passwordText => setPassword(passwordText)}
292 | errorMessage={
293 | isPasswordValid ? undefined : 'Please enter at least 8 characters'
294 | }
295 | {...testProperties('input-password')}
296 | />
297 | {isSignUpPage && (
298 | }
300 | value={passwordConfirmation}
301 | secureTextEntry={true}
302 | keyboardAppearance="light"
303 | autoCapitalize="none"
304 | autoCorrect={false}
305 | keyboardType="default"
306 | returnKeyType={'done'}
307 | blurOnSubmit={true}
308 | containerStyle={styles.containerStyle}
309 | inputContainerStyle={styles.inputContainerStyle}
310 | inputStyle={[
311 | styles.inputStyle,
312 | {color: isDarkMode ? Colors.white : Colors.black},
313 | ]}
314 | placeholder={'Confirm password'}
315 | ref={passwordConfirmationEl}
316 | onSubmitEditing={validateForm}
317 | onChangeText={passwordConfirmationText =>
318 | setPasswordConfirmation(passwordConfirmationText)
319 | }
320 | errorMessage={
321 | isConfirmationValid
322 | ? undefined
323 | : 'Please enter the same password'
324 | }
325 | {...testProperties('input-repeat-password')}
326 | />
327 | )}
328 | {isLoginPage && (
329 |
334 | When the device has Touch/FaceID (iOS) or FingerPrint enabled a
335 | biometrics button will be shown to use and test the login.
336 |
337 | )}
338 |
339 | {isBiometricAvailable && isLoginPage && (
340 |
345 | }
346 | textStyle={styles.buttonText}
347 | loading={isLoading}
348 | disabled={isLoading}
349 | testID="biometric"
350 | />
351 | )}
352 |
363 |
364 |
365 |
366 |
367 | );
368 | };
369 |
370 | const styles = StyleSheet.create({
371 | contentContainer: {
372 | alignItems: 'center',
373 | justifyContent: 'center',
374 | },
375 | titleContainer: {
376 | height: 150,
377 | backgroundColor: 'transparent',
378 | justifyContent: 'center',
379 | },
380 | categoryContainer: {
381 | flexDirection: 'row',
382 | },
383 | categoryText: {
384 | textAlign: 'center',
385 | fontSize: 24,
386 | backgroundColor: 'transparent',
387 | opacity: 0.54,
388 | },
389 | selectedCategoryText: {
390 | opacity: 1,
391 | },
392 | rowSelector: {
393 | height: 20,
394 | flexDirection: 'row',
395 | alignItems: 'center',
396 | },
397 | selectorContainer: {
398 | flex: 1,
399 | alignItems: 'center',
400 | },
401 | selected: {
402 | position: 'absolute',
403 | borderRadius: 50,
404 | height: 0,
405 | width: 0,
406 | top: -5,
407 | borderRightWidth: 70,
408 | borderBottomWidth: 70,
409 | borderColor: Colors.orange,
410 | backgroundColor: Colors.orange,
411 | },
412 | loginContainer: {
413 | alignItems: 'center',
414 | justifyContent: 'center',
415 | },
416 | formContainer: {
417 | borderRadius: 20,
418 | width: WINDOW_WIDTH - 30,
419 | paddingTop: 32,
420 | paddingBottom: 32,
421 | alignItems: 'center',
422 | borderColor: Colors.orange,
423 | borderWidth: 5,
424 | },
425 | buttonRow: {
426 | flexDirection: 'row',
427 | },
428 | biometricButton: {
429 | width: 65,
430 | marginRight: 15,
431 | },
432 | biometricIcon: {
433 | color: Colors.white,
434 | fontSize: 26,
435 | },
436 | biometricsText: {
437 | paddingHorizontal: 10,
438 | fontStyle: 'italic',
439 | },
440 | buttonText: {
441 | fontSize: 16,
442 | color: Colors.white,
443 | },
444 | button: {
445 | height: 50,
446 | width: 200,
447 | borderRadius: 5,
448 | backgroundColor: Colors.orange,
449 | borderColor: Colors.orange,
450 | borderWidth: 5,
451 | marginTop: 32,
452 | flex: 0,
453 | },
454 | buttonSmaller: {
455 | width: 150,
456 | },
457 | iconStyle: {
458 | fontSize: 25,
459 | color: Colors.orange,
460 | backgroundColor: 'transparent',
461 | },
462 | containerStyle: {
463 | marginTop: 16,
464 | },
465 | inputContainerStyle: {
466 | borderBottomColor: Colors.orange,
467 | },
468 | inputStyle: {
469 | marginLeft: 10,
470 | },
471 | });
472 |
473 | export default LoginForm;
474 |
--------------------------------------------------------------------------------
/src/components/SliderEntry.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {View, Text, StyleSheet, useColorScheme} from 'react-native';
3 | import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
4 | import {IS_IOS, WINDOW_HEIGHT, WINDOW_WIDTH} from '../config/Constants';
5 | import {testProperties} from '../config/TestProperties';
6 | import Colors from '../config/Colors';
7 |
8 | const itemHorizontalMargin = Math.round(WINDOW_WIDTH * 0.02);
9 | export const SLIDE_WIDTH =
10 | Math.round(WINDOW_WIDTH * 0.75) + itemHorizontalMargin * 2;
11 |
12 | const SliderEntry: React.FC<{
13 | icon: string;
14 | title: string;
15 | subtitle: string;
16 | }> = ({icon, title, subtitle}) => {
17 | const isDarkMode = useColorScheme() === 'dark';
18 |
19 | return (
20 |
26 |
27 |
28 |
29 |
32 |
38 | {title.toUpperCase()}
39 |
40 |
46 | {subtitle}
47 |
48 |
49 |
50 | );
51 | };
52 |
53 | const styles = StyleSheet.create({
54 | slideInnerContainer: {
55 | borderColor: Colors.orange,
56 | borderRadius: 20,
57 | borderWidth: 5,
58 | alignItems: 'center',
59 | width: SLIDE_WIDTH,
60 | height: Math.round(WINDOW_HEIGHT * 0.4),
61 | paddingHorizontal: itemHorizontalMargin,
62 | paddingTop: 18,
63 | },
64 | slideIconContainer: {
65 | flex: 1,
66 | marginBottom: IS_IOS ? 0 : -1, // Prevent a random Android rendering issue
67 | },
68 | slideIcon: {
69 | color: Colors.orange,
70 | },
71 | slideTextContainer: {
72 | paddingTop: 20,
73 | paddingBottom: 20,
74 | paddingHorizontal: 16,
75 | },
76 | slideTitle: {
77 | fontWeight: 'bold',
78 | textAlign: 'center',
79 | },
80 | slideSubtitle: {
81 | marginTop: 6,
82 | fontSize: 14,
83 | fontStyle: 'italic',
84 | textAlign: 'center',
85 | },
86 | });
87 |
88 | export default SliderEntry;
89 |
--------------------------------------------------------------------------------
/src/components/StatusBar.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {View, StyleSheet, StatusBar} from 'react-native';
3 |
4 | const STATUS_BAR_HEIGHT = StatusBar.currentHeight || 0;
5 |
6 | const WdioStatusBar = () => {
7 | return (
8 |
9 |
10 |
11 | );
12 | };
13 |
14 | const styles = StyleSheet.create({
15 | statusBar: {
16 | backgroundColor: '#000',
17 | position: 'absolute',
18 | top: 0,
19 | left: 0,
20 | zIndex: 100,
21 | width: '100%',
22 | height: STATUS_BAR_HEIGHT,
23 | },
24 | });
25 |
26 | export {STATUS_BAR_HEIGHT};
27 | export default WdioStatusBar;
28 |
--------------------------------------------------------------------------------
/src/components/TitleDivider.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {StyleSheet, Text, useColorScheme, View} from 'react-native';
3 | import Colors from '../config/Colors';
4 |
5 | const TitleDivider: React.FC<{text: string}> = ({text}) => {
6 | const isDarkMode = useColorScheme() === 'dark';
7 |
8 | return (
9 |
10 |
15 | {text}
16 |
17 |
18 | );
19 | };
20 |
21 | const styles = StyleSheet.create({
22 | titleContainer: {
23 | height: 150,
24 | backgroundColor: 'transparent',
25 | justifyContent: 'center',
26 | alignItems: 'center',
27 | },
28 | titleText: {
29 | fontSize: 30,
30 | fontWeight: '100',
31 | },
32 | });
33 |
34 | export default TitleDivider;
35 |
--------------------------------------------------------------------------------
/src/config/Colors.js:
--------------------------------------------------------------------------------
1 | export default {
2 | white: '#FFF',
3 | lighter: '#F7F7F7',
4 | light: '#DAE1E7',
5 | dark: '#1C1E21',
6 | darker: '#18191A',
7 | black: '#000',
8 | orange: '#ea5906',
9 | };
10 |
--------------------------------------------------------------------------------
/src/config/Constants.ts:
--------------------------------------------------------------------------------
1 | import {Platform, Dimensions} from 'react-native';
2 | import {hasNotch, hasDynamicIsland} from 'react-native-device-info';
3 |
4 | export const IS_IOS = Platform.OS === 'ios';
5 | export const {width: WINDOW_WIDTH, height: WINDOW_HEIGHT} =
6 | Dimensions.get('window');
7 | export const HAS_IOS_NOTCH = IS_IOS && (hasDynamicIsland() || hasNotch());
8 |
--------------------------------------------------------------------------------
/src/config/TestProperties.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Add a unique test id for iOS and Android
3 | *
4 | * NOTE: All touchable elements are accessible, meaning that it groups its children into a single selectable component,
5 | * sometimes this is not needed for testing and prevents getting proper data from elements. By providing
6 | * `disableAccessible = true` the elements should be visible / provide all needed data
7 | */
8 | import {IS_IOS} from './Constants';
9 |
10 | function testProperties(
11 | id: string,
12 | disableAccessible = false,
13 | ): {accessible?: boolean; accessibilityLabel?: string; testID?: string} {
14 | const disableAccessibility = disableAccessible ? {accessible: false} : {};
15 |
16 | if (IS_IOS) {
17 | return {...disableAccessibility, testID: id};
18 | }
19 |
20 | return {...disableAccessibility, accessibilityLabel: id};
21 | }
22 |
23 | export {testProperties};
24 |
--------------------------------------------------------------------------------
/src/screens/Drag.tsx:
--------------------------------------------------------------------------------
1 | import React, {useCallback, useRef, useState} from 'react';
2 | import {
3 | ImageBackground,
4 | PanResponderGestureState,
5 | StyleSheet,
6 | Text,
7 | TouchableOpacity,
8 | useColorScheme,
9 | View,
10 | } from 'react-native';
11 | import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
12 | import ConfettiCannon from 'react-native-confetti-cannon';
13 | import {testProperties} from '../config/TestProperties';
14 | import {STATUS_BAR_HEIGHT} from '../components/StatusBar';
15 | import Colors from '../config/Colors';
16 | import TitleDivider from '../components/TitleDivider';
17 | import Draggable from '../components/Draggable';
18 | import {HAS_IOS_NOTCH, WINDOW_HEIGHT, WINDOW_WIDTH} from '../config/Constants';
19 | import Button from '../components/Button';
20 |
21 | const DragScreen = () => {
22 | const isDarkMode = useColorScheme() === 'dark';
23 | const [resetOpacity, setResetOpacity] = useState(false);
24 | const [counter, setCounter] = useState(0);
25 | const dropZoneL1 = useRef(null);
26 | const dropZoneL2 = useRef(null);
27 | const dropZoneL3 = useRef(null);
28 | const dropZoneC1 = useRef(null);
29 | const dropZoneC2 = useRef(null);
30 | const dropZoneC3 = useRef(null);
31 | const dropZoneR1 = useRef(null);
32 | const dropZoneR2 = useRef(null);
33 | const dropZoneR3 = useRef(null);
34 | const dropZones = [
35 | dropZoneL1,
36 | dropZoneL2,
37 | dropZoneL3,
38 | dropZoneC1,
39 | dropZoneC2,
40 | dropZoneC3,
41 | dropZoneR1,
42 | dropZoneR2,
43 | dropZoneR3,
44 | ];
45 | const dropZoneValues = useRef<{
46 | top: number;
47 | bottom: number;
48 | left: number;
49 | right: number;
50 | }>();
51 | const isDropZoneStatus = useCallback((gesture: PanResponderGestureState) => {
52 | const dz = dropZoneValues.current;
53 |
54 | if (dz) {
55 | return (
56 | gesture.moveY > dz.top &&
57 | gesture.moveY < dz.bottom &&
58 | gesture.moveX > dz.left &&
59 | gesture.moveX < dz.right
60 | );
61 | }
62 |
63 | return false;
64 | }, []);
65 | const setDropZoneRectangles = (dropZone: any) => {
66 | dropZone.current?.measure(
67 | (
68 | fx: number,
69 | fy: number,
70 | width: number,
71 | height: number,
72 | px: number,
73 | py: number,
74 | ) => {
75 | dropZoneValues.current = {
76 | bottom: py + height,
77 | left: px,
78 | right: px + width,
79 | top: py,
80 | };
81 | },
82 | );
83 | };
84 | const puzzlePieces = [
85 | {
86 | dropZone: dropZoneL2,
87 | isDropZone: isDropZoneStatus,
88 | setDropZoneValues: setDropZoneRectangles,
89 | src: require('../assets/images/wdio-l2.png'),
90 | testID: 'drag-l2',
91 | },
92 | {
93 | dropZone: dropZoneR3,
94 | isDropZone: isDropZoneStatus,
95 | setDropZoneValues: setDropZoneRectangles,
96 | src: require('../assets/images/wdio-r3.png'),
97 | testID: 'drag-r3',
98 | },
99 | {
100 | dropZone: dropZoneR1,
101 | isDropZone: isDropZoneStatus,
102 | setDropZoneValues: setDropZoneRectangles,
103 | src: require('../assets/images/wdio-r1.png'),
104 | testID: 'drag-r1',
105 | },
106 | {
107 | dropZone: dropZoneC1,
108 | isDropZone: isDropZoneStatus,
109 | setDropZoneValues: setDropZoneRectangles,
110 | src: require('../assets/images/wdio-c1.png'),
111 | testID: 'drag-c1',
112 | },
113 | {
114 | dropZone: dropZoneC3,
115 | isDropZone: isDropZoneStatus,
116 | setDropZoneValues: setDropZoneRectangles,
117 | src: require('../assets/images/wdio-c3.png'),
118 | testID: 'drag-c3',
119 | },
120 | {
121 | dropZone: dropZoneR2,
122 | isDropZone: isDropZoneStatus,
123 | setDropZoneValues: setDropZoneRectangles,
124 | src: require('../assets/images/wdio-r2.png'),
125 | testID: 'drag-r2',
126 | },
127 | {
128 | dropZone: dropZoneC2,
129 | isDropZone: isDropZoneStatus,
130 | setDropZoneValues: setDropZoneRectangles,
131 | src: require('../assets/images/wdio-c2.png'),
132 | testID: 'drag-c2',
133 | },
134 | {
135 | dropZone: dropZoneL1,
136 | isDropZone: isDropZoneStatus,
137 | setDropZoneValues: setDropZoneRectangles,
138 | src: require('../assets/images/wdio-l1.png'),
139 | testID: 'drag-l1',
140 | },
141 | {
142 | dropZone: dropZoneL3,
143 | isDropZone: isDropZoneStatus,
144 | setDropZoneValues: setDropZoneRectangles,
145 | src: require('../assets/images/wdio-l3.png'),
146 | testID: 'drag-l3',
147 | },
148 | ];
149 | const updateCounter = () => setCounter(counter + 1);
150 | const resetPuzzle = () => {
151 | setResetOpacity(true);
152 | dropZones.forEach(dropZone =>
153 | dropZone.current?.setNativeProps({style: {opacity: 1}}),
154 | );
155 | setCounter(0);
156 | setTimeout(() => setResetOpacity(false), 1);
157 | };
158 |
159 | return (
160 |
166 | {counter === 9 && (
167 |
172 |
179 |
180 |
181 | You made it, click retry if you want to try it again.
182 |
183 | resetPuzzle()}
186 | textStyle={[
187 | {
188 | color: isDarkMode ? Colors.white : Colors.black,
189 | },
190 | ]}
191 | text="Retry"
192 | />
193 |
194 | )}
195 |
196 |
197 |
200 |
204 |
205 |
206 |
210 |
211 |
212 |
216 |
217 |
218 |
222 |
223 |
224 |
228 |
229 |
230 |
234 |
235 |
236 |
240 |
241 |
242 |
246 |
247 |
248 |
252 |
253 |
254 |
255 | resetPuzzle()}
257 | style={styles.renewIcon}
258 | {...testProperties('renew')}>
259 |
264 |
265 |
266 | {puzzlePieces.map(
267 | ({dropZone, isDropZone, setDropZoneValues, src, testID}, index) => (
268 |
278 | ),
279 | )}
280 |
281 |
282 |
283 | );
284 | };
285 |
286 | const styles = StyleSheet.create({
287 | container: {
288 | flex: 1,
289 | marginTop: STATUS_BAR_HEIGHT,
290 | },
291 | contentContainer: {
292 | flex: 1,
293 | paddingHorizontal: 10,
294 | paddingBottom: 10,
295 | alignItems: 'center',
296 | },
297 | successContainer: {
298 | // backgroundColor: Colors.dark,
299 | alignItems: 'center',
300 | justifyContent: 'center',
301 | height: WINDOW_HEIGHT - (HAS_IOS_NOTCH ? 100 : 55),
302 | width: WINDOW_WIDTH,
303 | position: 'absolute',
304 | left: 0,
305 | top: 0,
306 | zIndex: 10,
307 | },
308 | button: {
309 | height: 50,
310 | width: 200,
311 | borderRadius: 5,
312 | backgroundColor: Colors.orange,
313 | borderColor: Colors.orange,
314 | borderWidth: 5,
315 | marginTop: 32,
316 | flex: 0,
317 | },
318 | dropZoneContainer: {
319 | flexDirection: 'row',
320 | flexWrap: 'wrap',
321 | width: 250,
322 | height: 250,
323 | },
324 | disabledDropZone: {
325 | backgroundColor: Colors.white,
326 | opacity: 0.7,
327 | flex: 1,
328 | },
329 | orangeBorder: {
330 | borderColor: Colors.orange,
331 | borderWidth: 1,
332 | },
333 | dropZone83x83: {
334 | width: 82,
335 | height: 82,
336 | },
337 | dropZone83x84: {
338 | width: 82,
339 | height: 83,
340 | },
341 | dropZone84x83: {
342 | width: 83,
343 | height: 82,
344 | },
345 | dropZone84x84: {
346 | width: 83,
347 | height: 83,
348 | },
349 | dropZone: {
350 | height: 250,
351 | width: '100%',
352 | alignItems: 'center',
353 | opacity: 0.2,
354 | },
355 | logo: {
356 | height: 250,
357 | width: 250,
358 | },
359 | dragZone: {
360 | flexDirection: 'row',
361 | flexWrap: 'wrap',
362 | position: 'absolute',
363 | bottom: 10,
364 | left: 10,
365 | width: '100%',
366 | justifyContent: 'center',
367 | alignItems: 'center',
368 | alignContent: 'center',
369 | },
370 | renewIcon: {
371 | marginTop: 15,
372 | },
373 | });
374 |
375 | export default DragScreen;
376 |
--------------------------------------------------------------------------------
/src/screens/Forms.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {ScrollView, StyleSheet, useColorScheme} from 'react-native';
3 | import FormComponents from '../components/FormComponents';
4 | import {STATUS_BAR_HEIGHT} from '../components/StatusBar';
5 | import {testProperties} from '../config/TestProperties';
6 | import Colors from '../config/Colors';
7 |
8 | const FormsScreen = () => {
9 | const isDarkMode = useColorScheme() === 'dark';
10 |
11 | return (
12 |
19 |
20 |
21 | );
22 | };
23 |
24 | const styles = StyleSheet.create({
25 | container: {
26 | flex: 1,
27 | marginTop: STATUS_BAR_HEIGHT,
28 | paddingBottom: 40,
29 | },
30 | });
31 |
32 | export default FormsScreen;
33 |
--------------------------------------------------------------------------------
/src/screens/Home.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | Image,
4 | ScrollView,
5 | StyleSheet,
6 | Text,
7 | useColorScheme,
8 | View,
9 | } from 'react-native';
10 | import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
11 | import {testProperties} from '../config/TestProperties';
12 | import {STATUS_BAR_HEIGHT} from '../components/StatusBar';
13 | import Colors from '../config/Colors';
14 |
15 | const HomeScreen = () => {
16 | const isDarkMode = useColorScheme() === 'dark';
17 |
18 | return (
19 |
25 |
26 |
30 |
31 |
36 | WEBDRIVER
37 |
38 |
39 |
40 |
45 | Demo app for the appium-boilerplate
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
60 | Support
61 |
62 |
63 |
64 | );
65 | };
66 |
67 | const styles = StyleSheet.create({
68 | container: {
69 | flex: 1,
70 | marginTop: STATUS_BAR_HEIGHT,
71 | paddingBottom: 40,
72 | },
73 | contentContainer: {
74 | flex: 1,
75 | alignItems: 'center',
76 | justifyContent: 'center',
77 | width: '100%',
78 | height: '100%',
79 | },
80 | logo: {
81 | marginTop: 100,
82 | height: 250,
83 | width: 250,
84 | },
85 | io: {
86 | height: 50,
87 | width: 50,
88 | },
89 | logoTextContainer: {
90 | flexDirection: 'row',
91 | paddingTop: 20,
92 | paddingBottom: 10,
93 | },
94 | regularFont: {
95 | fontWeight: '100',
96 | fontSize: 16,
97 | },
98 | logoText: {
99 | textTransform: 'uppercase',
100 | backgroundColor: 'transparent',
101 | textAlign: 'center',
102 | fontSize: 40,
103 | fontWeight: '100',
104 | },
105 | platformIconContainer: {
106 | flexDirection: 'row',
107 | paddingTop: 10,
108 | paddingBottom: 10,
109 | },
110 | orangeColor: {
111 | color: Colors.orange,
112 | },
113 | });
114 |
115 | export default HomeScreen;
116 |
--------------------------------------------------------------------------------
/src/screens/Login.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {ScrollView, StyleSheet, useColorScheme} from 'react-native';
3 | import LoginForm from '../components/LoginForm';
4 | import {STATUS_BAR_HEIGHT} from '../components/StatusBar';
5 | import {testProperties} from '../config/TestProperties';
6 | import Colors from '../config/Colors';
7 |
8 | const LoginScreen = () => {
9 | const isDarkMode = useColorScheme() === 'dark';
10 |
11 | return (
12 |
19 |
20 |
21 | );
22 | };
23 |
24 | const styles = StyleSheet.create({
25 | container: {
26 | flex: 1,
27 | marginTop: STATUS_BAR_HEIGHT,
28 | paddingBottom: 40,
29 | },
30 | });
31 |
32 | export default LoginScreen;
33 |
--------------------------------------------------------------------------------
/src/screens/Swipe.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | Image,
4 | ScrollView,
5 | StyleSheet,
6 | Text,
7 | useColorScheme,
8 | View,
9 | } from 'react-native';
10 | import type {ICarouselInstance} from 'react-native-reanimated-carousel';
11 | import Carousel from 'react-native-reanimated-carousel';
12 | import {STATUS_BAR_HEIGHT} from '../components/StatusBar';
13 | import TitleDivider from '../components/TitleDivider';
14 | import SliderEntry from '../components/SliderEntry';
15 | import {HAS_IOS_NOTCH, WINDOW_HEIGHT, WINDOW_WIDTH} from '../config/Constants';
16 | import {testProperties} from '../config/TestProperties';
17 | import Colors from '../config/Colors';
18 |
19 | interface SliderEntries {
20 | title: string;
21 | subtitle: string;
22 | icon: string;
23 | }
24 | const ENTRIES1: SliderEntries[] = [
25 | {
26 | title: 'Fully Open Source',
27 | subtitle: 'WebdriverIO is fully open source and can be found on GitHub',
28 | icon: 'github',
29 | },
30 | {
31 | title: 'Great community',
32 | subtitle: 'WebdriverIO has a great community that supports all members.',
33 | icon: 'wechat',
34 | },
35 | {
36 | title: 'JS.Foundation',
37 | subtitle:
38 | 'The JS Foundation is host to projects that span the entire JavaScript ecosystem.',
39 | icon: 'language-javascript',
40 | },
41 | {
42 | title: 'Support Videos',
43 | subtitle:
44 | 'The community around WebdriverIO is actively speaking on various user groups or conferences about specific topics around automated testing with WebdriverIO.',
45 | icon: 'youtube',
46 | },
47 | {
48 | title: 'Extendable',
49 | subtitle:
50 | 'Adding helper functions, or more complicated sets and combinations of existing commands is simple and really useful',
51 | icon: 'engine-outline',
52 | },
53 | {
54 | title: 'Compatible',
55 | subtitle:
56 | 'WebdriverIO works in combination with most of the TDD and BDD test frameworks in the JavaScript world',
57 | icon: 'arrow-decision-outline',
58 | },
59 | ];
60 | const Item: React.FC<{item: SliderEntries}> = ({item}) => {
61 | return ;
62 | };
63 |
64 | const SwipeScreen = () => {
65 | const isDarkMode = useColorScheme() === 'dark';
66 |
67 | const ref = React.useRef(null);
68 |
69 | const baseOptions = {
70 | vertical: false,
71 | width: WINDOW_WIDTH * 0.85,
72 | } as const;
73 |
74 | return (
75 |
81 |
82 |
83 |
88 | Or swipe vertical to find what I'm hiding.
89 |
90 |
91 |
102 |
103 |
104 |
105 |
110 |
115 | You found me!!!
116 |
117 |
118 |
119 | );
120 | };
121 |
122 | const styles = StyleSheet.create({
123 | container: {
124 | flex: 1,
125 | marginTop: STATUS_BAR_HEIGHT,
126 | paddingBottom: 40,
127 | },
128 | horizontalContainer: {
129 | height: WINDOW_HEIGHT - (HAS_IOS_NOTCH ? 100 : 55),
130 | flexDirection: 'column',
131 | justifyContent: 'space-around',
132 | },
133 | subText: {
134 | textAlign: 'center',
135 | },
136 | sliderContainer: {
137 | width: '100%',
138 | },
139 | logoContainer: {
140 | flex: 1,
141 | alignSelf: 'center',
142 | marginBottom: 20,
143 | paddingTop: 500,
144 | },
145 | logoText: {
146 | fontStyle: 'italic',
147 | textAlign: 'center',
148 | },
149 | logo: {
150 | marginTop: 100,
151 | height: 250,
152 | width: 250,
153 | },
154 | });
155 |
156 | export default SwipeScreen;
157 |
--------------------------------------------------------------------------------
/src/screens/WebView.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {StyleSheet, useColorScheme, View} from 'react-native';
3 | import {WebView} from 'react-native-webview';
4 | import BorderText from '../components/BorderText';
5 | import {STATUS_BAR_HEIGHT} from '../components/StatusBar';
6 | import Colors from '../config/Colors';
7 |
8 | const RenderLoading: React.FC<{isDarkMode: boolean}> = ({isDarkMode}) => {
9 | return (
10 |
15 |
16 |
17 | );
18 | };
19 | const WebviewScreen = () => {
20 | const isDarkMode = useColorScheme() === 'dark';
21 |
22 | return (
23 | }
25 | source={{uri: 'https://webdriver.io/'}}
26 | startInLoadingState
27 | originWhitelist={['*']}
28 | style={{marginTop: STATUS_BAR_HEIGHT}}
29 | webviewDebuggingEnabled
30 | />
31 | );
32 | };
33 |
34 | const styles = StyleSheet.create({
35 | loaderContainer: {
36 | flex: 1,
37 | flexDirection: 'column',
38 | justifyContent: 'center',
39 | alignItems: 'center',
40 | position: 'absolute',
41 | top: 0,
42 | left: 0,
43 | bottom: 0,
44 | right: 0,
45 | },
46 | });
47 |
48 | export default WebviewScreen;
49 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@react-native/typescript-config/tsconfig.json"
3 | }
4 |
--------------------------------------------------------------------------------