From 15f2092d633f7a0cc95a69a024cffcbdbdc0b750 Mon Sep 17 00:00:00 2001 From: Georgy Steshin Date: Sun, 1 Dec 2024 18:42:00 +0200 Subject: [PATCH 01/24] Upgrade to rn 75 --- detox/android/build.gradle | 2 +- detox/android/detox/build.gradle | 4 ++++ .../gradle/wrapper/gradle-wrapper.properties | 2 +- detox/android/rninfo.gradle | 1 + detox/android/settings.gradle | 12 +++++++++--- detox/scripts/updateGradle.js | 2 ++ detox/test/android/app/build.gradle | 3 +++ detox/test/android/build.gradle | 2 +- detox/test/android/gradle.properties | 2 -- .../gradle/wrapper/gradle-wrapper.properties | 2 +- detox/test/android/settings.gradle | 13 ++++++++++--- detox/test/ios/example.xcodeproj/project.pbxproj | 4 ++-- detox/test/package.json | 14 ++++++++------ 13 files changed, 43 insertions(+), 20 deletions(-) diff --git a/detox/android/build.gradle b/detox/android/build.gradle index 2afce02933..ed43b4202a 100644 --- a/detox/android/build.gradle +++ b/detox/android/build.gradle @@ -3,7 +3,7 @@ buildscript { ext { isOfficialDetoxLib = true - kotlinVersion = '1.9.20' + kotlinVersion = '1.9.24' dokkaVersion = '1.9.10' buildToolsVersion = '34.0.0' compileSdkVersion = 34 diff --git a/detox/android/detox/build.gradle b/detox/android/detox/build.gradle index 660025b6ef..3b7ea0c7a9 100644 --- a/detox/android/detox/build.gradle +++ b/detox/android/detox/build.gradle @@ -22,6 +22,10 @@ def _rnNativeArtifact = rnInfo.isRN71OrHigher println "[$project] Resorted to RN native artifact $_rnNativeArtifact" +react { + autolinkLibrariesWithApp() +} + android { def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')[0].toInteger() if (agpVersion >= 7) { diff --git a/detox/android/gradle/wrapper/gradle-wrapper.properties b/detox/android/gradle/wrapper/gradle-wrapper.properties index a80b22ce5c..a4413138c9 100644 --- a/detox/android/gradle/wrapper/gradle-wrapper.properties +++ b/detox/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/detox/android/rninfo.gradle b/detox/android/rninfo.gradle index eb7d649af3..284920b9d5 100644 --- a/detox/android/rninfo.gradle +++ b/detox/android/rninfo.gradle @@ -41,4 +41,5 @@ ext.rnInfo = [ isRN72OrHigher: rnMajorVer >= 72, isRN73OrHigher: rnMajorVer >= 73, isRN74OrHigher: rnMajorVer >= 74, + isRN75OrHigher: rnMajorVer >= 75, ] diff --git a/detox/android/settings.gradle b/detox/android/settings.gradle index 2541ebac02..a73c8f0bca 100644 --- a/detox/android/settings.gradle +++ b/detox/android/settings.gradle @@ -5,8 +5,14 @@ println("RNInfo: rootDir=$rootDir") println "[settings] RNInfo: detected React Native version: (major=${ext.rnInfo.version})" -if (ext.rnInfo.isRN72OrHigher) { - includeBuild('../node_modules/@react-native/gradle-plugin') +if (ext.rnInfo.isRN75OrHigher) { + pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") } + plugins { id("com.facebook.react.settings") } + extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() } } else { - includeBuild('../node_modules/react-native-gradle-plugin') + if (ext.rnInfo.isRN72OrHigher) { + includeBuild('../node_modules/@react-native/gradle-plugin') + } else { + includeBuild('../node_modules/react-native-gradle-plugin') + } } diff --git a/detox/scripts/updateGradle.js b/detox/scripts/updateGradle.js index 6d525edb9e..ed941871bd 100644 --- a/detox/scripts/updateGradle.js +++ b/detox/scripts/updateGradle.js @@ -6,6 +6,8 @@ const rnMinor = require('../src/utils/rn-consts/rn-consts').rnVersion.minor; function getGradleVersionByRNVersion() { switch (rnMinor) { default: + return '8.8'; + case '74': return '8.6'; case '73': return '8.3'; diff --git a/detox/test/android/app/build.gradle b/detox/test/android/app/build.gradle index 3363cf85b7..24c1051b17 100644 --- a/detox/test/android/app/build.gradle +++ b/detox/test/android/app/build.gradle @@ -3,6 +3,9 @@ apply plugin: 'com.facebook.react' apply plugin: 'kotlin-android' apply from: '../../../android/rninfo.gradle' +react { + autolinkLibrariesWithApp() +} android { namespace 'com.example' diff --git a/detox/test/android/build.gradle b/detox/test/android/build.gradle index 7e52890931..212a3b6547 100644 --- a/detox/test/android/build.gradle +++ b/detox/test/android/build.gradle @@ -3,7 +3,7 @@ buildscript { ext { isOfficialDetoxApp = true - kotlinVersion = '1.9.20' + kotlinVersion = '1.9.24' buildToolsVersion = '34.0.0' compileSdkVersion = 34 targetSdkVersion = 34 diff --git a/detox/test/android/gradle.properties b/detox/test/android/gradle.properties index a5fa801dff..964f22392f 100644 --- a/detox/test/android/gradle.properties +++ b/detox/test/android/gradle.properties @@ -21,8 +21,6 @@ org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m # Android operating system, and which are packaged with your app's APK # https://developer.android.com/topic/libraries/support-library/androidx-rn android.useAndroidX=true -# Automatically convert third-party libraries to use AndroidX -android.enableJetifier=true # Use this property to enable or disable the Hermes JS engine. # If set to false, you will be using JSC instead. diff --git a/detox/test/android/gradle/wrapper/gradle-wrapper.properties b/detox/test/android/gradle/wrapper/gradle-wrapper.properties index a80b22ce5c..a4413138c9 100644 --- a/detox/test/android/gradle/wrapper/gradle-wrapper.properties +++ b/detox/test/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/detox/test/android/settings.gradle b/detox/test/android/settings.gradle index 817e335210..a722678bc8 100644 --- a/detox/test/android/settings.gradle +++ b/detox/test/android/settings.gradle @@ -4,12 +4,19 @@ include ':app' println "[settings] RNInfo: detected React Native version: (major=${ext.rnInfo.version})" -if (ext.rnInfo.isRN72OrHigher) { - includeBuild('../node_modules/@react-native/gradle-plugin') +if (ext.rnInfo.isRN75OrHigher) { + pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") } + plugins { id("com.facebook.react.settings") } + extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() } } else { - includeBuild('../node_modules/react-native-gradle-plugin') + if (ext.rnInfo.isRN72OrHigher) { + includeBuild('../node_modules/@react-native/gradle-plugin') + } else { + includeBuild('../node_modules/react-native-gradle-plugin') + } } + include ':detox' project(':detox').projectDir = new File(rootProject.projectDir, '../../android/detox') diff --git a/detox/test/ios/example.xcodeproj/project.pbxproj b/detox/test/ios/example.xcodeproj/project.pbxproj index fead653f31..fae2810498 100644 --- a/detox/test/ios/example.xcodeproj/project.pbxproj +++ b/detox/test/ios/example.xcodeproj/project.pbxproj @@ -94,7 +94,7 @@ 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = example/Images.xcassets; sourceTree = ""; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = example/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = example/main.m; sourceTree = ""; }; - 18AB08AE5A45E52755A8055D /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = example/PrivacyInfo.xcprivacy; sourceTree = ""; }; + 18AB08AE5A45E52755A8055D /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = example/PrivacyInfo.xcprivacy; sourceTree = ""; }; 399B4E061ED587120098D2AC /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 39B0445B1DAED76400431EC5 /* Detox.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Detox.xcodeproj; path = ../../ios/Detox.xcodeproj; sourceTree = ""; }; 39B71FC924643AEA00CC9A88 /* exampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = exampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -108,7 +108,7 @@ 6027065D2B1DF4DD00CD52CF /* example.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = example.entitlements; path = example/example.entitlements; sourceTree = ""; }; 6027065F2B1DF82400CD52CF /* example_ci.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = example_ci.entitlements; sourceTree = ""; }; 6CEAF92A5314EC6824AB3DE3 /* libPods-example_ci.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-example_ci.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 75C5679B8378704E8D3D9C66 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = example/PrivacyInfo.xcprivacy; sourceTree = ""; }; + 75C5679B8378704E8D3D9C66 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = example/PrivacyInfo.xcprivacy; sourceTree = ""; }; 86172A40F266BB07F101EB18 /* libPods-example.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-example.a"; sourceTree = BUILT_PRODUCTS_DIR; }; A112C2B84196BF64AE1EFFA3 /* Pods-example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example.debug.xcconfig"; path = "Target Support Files/Pods-example/Pods-example.debug.xcconfig"; sourceTree = ""; }; A398C1445E8C769F5903CD2D /* Pods-example_ci.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example_ci.debug.xcconfig"; path = "Target Support Files/Pods-example_ci/Pods-example_ci.debug.xcconfig"; sourceTree = ""; }; diff --git a/detox/test/package.json b/detox/test/package.json index 70f6618d15..e4eca36e65 100644 --- a/detox/test/package.json +++ b/detox/test/package.json @@ -39,8 +39,8 @@ "@react-native-picker/picker": "^2.1.0", "@react-native-segmented-control/segmented-control": "2.3.0", "moment": "^2.24.0", - "react": "18.2.0", - "react-native": "0.74.6", + "react": "18.3.1", + "react-native": "0.75.4", "react-native-launch-arguments": "^4.0.0", "react-native-permissions": "^4.0.2", "react-native-webview": "^11.18.1", @@ -50,10 +50,12 @@ "@babel/core": "^7.20.0", "@babel/preset-env": "^7.20.0", "@babel/runtime": "^7.20.0", - "@react-native/babel-preset": "0.74.88", - "@react-native/eslint-config": "0.74.88", - "@react-native/metro-config": "0.74.88", - "@react-native/typescript-config": "0.74.88", + + "@react-native/babel-preset": "0.75.4", + "@react-native/eslint-config": "0.75.4", + "@react-native/metro-config": "0.75.4", + "@react-native/typescript-config": "0.75.4", + "@tsconfig/react-native": "^3.0.0", "@types/jest": "^29.5.11", "@types/node": "^16.18.68", From 4a12472fb3d15c4744ebfcfac382e69d873897ac Mon Sep 17 00:00:00 2001 From: Georgy Steshin Date: Sun, 1 Dec 2024 18:47:14 +0200 Subject: [PATCH 02/24] Upgrade to rn 75 --- detox/package.json | 10 +++++----- detox/test/ios/example.xcodeproj/project.pbxproj | 1 + detox/test/package.json | 2 -- .../android/gradle/wrapper/gradle-wrapper.properties | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/detox/package.json b/detox/package.json index 6eda1654a8..7b51cdc2bd 100644 --- a/detox/package.json +++ b/detox/package.json @@ -34,10 +34,10 @@ "postinstall": "node scripts/postinstall.js" }, "devDependencies": { - "@react-native/babel-preset": "0.74.88", - "@react-native/eslint-config": "0.74.88", - "@react-native/metro-config": "0.74.88", - "@react-native/typescript-config": "0.74.88", + "@react-native/babel-preset": "0.75.4", + "@react-native/eslint-config": "0.75.4", + "@react-native/metro-config": "0.75.4", + "@react-native/typescript-config": "0.75.4", "@tsconfig/react-native": "^3.0.0", "@types/bunyan": "^1.8.8", "@types/child-process-promise": "^2.2.1", @@ -59,7 +59,7 @@ "jest-allure2-reporter": "^2.0.0-beta.18", "metro-react-native-babel-preset": "0.76.8", "prettier": "^3.1.1", - "react-native": "0.74.6", + "react-native": "0.75.4", "react-native-codegen": "^0.0.8", "typescript": "^5.3.3", "wtfnode": "^0.9.1" diff --git a/detox/test/ios/example.xcodeproj/project.pbxproj b/detox/test/ios/example.xcodeproj/project.pbxproj index fae2810498..95434ed05e 100644 --- a/detox/test/ios/example.xcodeproj/project.pbxproj +++ b/detox/test/ios/example.xcodeproj/project.pbxproj @@ -817,6 +817,7 @@ OTHER_LDFLAGS = "$(inherited)"; REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG"; USE_HERMES = false; }; name = Debug; diff --git a/detox/test/package.json b/detox/test/package.json index e4eca36e65..de42e7acf4 100644 --- a/detox/test/package.json +++ b/detox/test/package.json @@ -50,12 +50,10 @@ "@babel/core": "^7.20.0", "@babel/preset-env": "^7.20.0", "@babel/runtime": "^7.20.0", - "@react-native/babel-preset": "0.75.4", "@react-native/eslint-config": "0.75.4", "@react-native/metro-config": "0.75.4", "@react-native/typescript-config": "0.75.4", - "@tsconfig/react-native": "^3.0.0", "@types/jest": "^29.5.11", "@types/node": "^16.18.68", diff --git a/examples/demo-react-native/android/gradle/wrapper/gradle-wrapper.properties b/examples/demo-react-native/android/gradle/wrapper/gradle-wrapper.properties index a80b22ce5c..a4413138c9 100644 --- a/examples/demo-react-native/android/gradle/wrapper/gradle-wrapper.properties +++ b/examples/demo-react-native/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From c56efda2bd9c96f5557955b8bda2017c42350c7f Mon Sep 17 00:00:00 2001 From: Georgy Steshin Date: Sun, 1 Dec 2024 19:09:01 +0200 Subject: [PATCH 03/24] Added rn 75 pipelines --- ...74.yml => pipeline.android_demo_app_rn_75.yml} | 4 ++-- .buildkite/jobs/pipeline.android_rn_75.yml | 12 ++++++++++++ .buildkite/jobs/pipeline.ios_demo_app_rn_75.yml | 9 +++++++++ .buildkite/jobs/pipeline.ios_rn_75.yml | 10 ++++++++++ .buildkite/pipeline_common.sh | 5 ++++- detox/android/detox/build.gradle | 4 ---- detox/test/android/settings.gradle | 15 +++++++-------- 7 files changed, 44 insertions(+), 15 deletions(-) rename .buildkite/jobs/{pipeline.android_demo_app_rn_74.yml => pipeline.android_demo_app_rn_75.yml} (81%) create mode 100644 .buildkite/jobs/pipeline.android_rn_75.yml create mode 100644 .buildkite/jobs/pipeline.ios_demo_app_rn_75.yml create mode 100644 .buildkite/jobs/pipeline.ios_rn_75.yml diff --git a/.buildkite/jobs/pipeline.android_demo_app_rn_74.yml b/.buildkite/jobs/pipeline.android_demo_app_rn_75.yml similarity index 81% rename from .buildkite/jobs/pipeline.android_demo_app_rn_74.yml rename to .buildkite/jobs/pipeline.android_demo_app_rn_75.yml index 131da20242..2b76e23d0a 100644 --- a/.buildkite/jobs/pipeline.android_demo_app_rn_74.yml +++ b/.buildkite/jobs/pipeline.android_demo_app_rn_75.yml @@ -1,9 +1,9 @@ - - label: ":android::react: RN .74 + Android: Demo app" + - label: ":android::react: RN .75 + Android: Demo app" command: - "nvm install" - "./scripts/demo-projects.android.sh" env: - REACT_NATIVE_VERSION: 0.74.6 + REACT_NATIVE_VERSION: 0.75.4 REACT_NATIVE_COMPAT_TEST: true # Only set 'true' in jobs with the latest supported RN DETOX_DISABLE_POD_INSTALL: true DETOX_DISABLE_POSTINSTALL: true diff --git a/.buildkite/jobs/pipeline.android_rn_75.yml b/.buildkite/jobs/pipeline.android_rn_75.yml new file mode 100644 index 0000000000..0b6b51e256 --- /dev/null +++ b/.buildkite/jobs/pipeline.android_rn_75.yml @@ -0,0 +1,12 @@ + - label: ":android::detox: RN .75 + Android: Tests app" + command: + - "nvm install" + - "./scripts/ci.android.sh" + env: + REACT_NATIVE_VERSION: 0.75.4 + DETOX_DISABLE_POD_INSTALL: true + DETOX_DISABLE_POSTINSTALL: true + artifact_paths: + - "/Users/builder/uibuilder/work/coverage/**/*.lcov" + - "/Users/builder/uibuilder/work/**/allure-report-*.html" + - "/Users/builder/uibuilder/work/artifacts*.tar.gz" diff --git a/.buildkite/jobs/pipeline.ios_demo_app_rn_75.yml b/.buildkite/jobs/pipeline.ios_demo_app_rn_75.yml new file mode 100644 index 0000000000..623b1e35c6 --- /dev/null +++ b/.buildkite/jobs/pipeline.ios_demo_app_rn_75.yml @@ -0,0 +1,9 @@ + - label: ":ios::react: RN .75 + iOS: Demo app" + command: + - "nvm install" + - "./scripts/demo-projects.ios.sh" + env: + REACT_NATIVE_VERSION: 0.75.4 + artifact_paths: + - "/Users/builder/uibuilder/work/coverage/**/*.lcov" + - "/Users/builder/uibuilder/work/artifacts*.tar.gz" diff --git a/.buildkite/jobs/pipeline.ios_rn_75.yml b/.buildkite/jobs/pipeline.ios_rn_75.yml new file mode 100644 index 0000000000..71332023d9 --- /dev/null +++ b/.buildkite/jobs/pipeline.ios_rn_75.yml @@ -0,0 +1,10 @@ + - label: ":ios::detox: RN .75 + iOS: Tests app" + command: + - "nvm install" + - "./scripts/ci.ios.sh" + env: + REACT_NATIVE_VERSION: 0.75.4 + artifact_paths: + - "/Users/builder/uibuilder/work/coverage/**/*.lcov" + - "/Users/builder/uibuilder/work/**/allure-report-*.html" + - "/Users/builder/uibuilder/work/artifacts*.tar.gz" diff --git a/.buildkite/pipeline_common.sh b/.buildkite/pipeline_common.sh index e4601d69fd..0ce726fa02 100755 --- a/.buildkite/pipeline_common.sh +++ b/.buildkite/pipeline_common.sh @@ -2,11 +2,14 @@ echo "steps:" +cat .buildkite/jobs/pipeline.ios_rn_75.yml cat .buildkite/jobs/pipeline.ios_rn_74.yml cat .buildkite/jobs/pipeline.ios_rn_73.yml +cat .buildkite/jobs/pipeline.ios_demo_app_rn_75.yml cat .buildkite/jobs/pipeline.ios_demo_app_rn_74.yml cat .buildkite/jobs/pipeline.ios_demo_app_rn_73.yml +cat .buildkite/jobs/pipeline.android_rn_75.yml cat .buildkite/jobs/pipeline.android_rn_74.yml cat .buildkite/jobs/pipeline.android_rn_73.yml -cat .buildkite/jobs/pipeline.android_demo_app_rn_74.yml +cat .buildkite/jobs/pipeline.android_demo_app_rn_75.yml cat .buildkite/pipeline.post_processing.yml diff --git a/detox/android/detox/build.gradle b/detox/android/detox/build.gradle index 3b7ea0c7a9..660025b6ef 100644 --- a/detox/android/detox/build.gradle +++ b/detox/android/detox/build.gradle @@ -22,10 +22,6 @@ def _rnNativeArtifact = rnInfo.isRN71OrHigher println "[$project] Resorted to RN native artifact $_rnNativeArtifact" -react { - autolinkLibrariesWithApp() -} - android { def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')[0].toInteger() if (agpVersion >= 7) { diff --git a/detox/test/android/settings.gradle b/detox/test/android/settings.gradle index a722678bc8..44240401b6 100644 --- a/detox/test/android/settings.gradle +++ b/detox/test/android/settings.gradle @@ -1,6 +1,4 @@ apply from: file("../../android/rninfo.gradle") -rootProject.name = 'DetoxTest' -include ':app' println "[settings] RNInfo: detected React Native version: (major=${ext.rnInfo.version})" @@ -8,14 +6,15 @@ if (ext.rnInfo.isRN75OrHigher) { pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") } plugins { id("com.facebook.react.settings") } extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() } -} else { - if (ext.rnInfo.isRN72OrHigher) { - includeBuild('../node_modules/@react-native/gradle-plugin') - } else { - includeBuild('../node_modules/react-native-gradle-plugin') - } } +if (ext.rnInfo.isRN72OrHigher) { + includeBuild('../node_modules/@react-native/gradle-plugin') +} else { + includeBuild('../node_modules/react-native-gradle-plugin') +} +rootProject.name = 'DetoxTest' +include ':app' include ':detox' project(':detox').projectDir = new File(rootProject.projectDir, '../../android/detox') From 0a630767187286f2306a3a51526eb4ca6cfc3cda Mon Sep 17 00:00:00 2001 From: Georgy Steshin Date: Sun, 1 Dec 2024 19:25:32 +0200 Subject: [PATCH 04/24] Fixed build on rn < 75 --- detox/test/android/app/build.gradle | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/detox/test/android/app/build.gradle b/detox/test/android/app/build.gradle index 24c1051b17..b5626f7dcc 100644 --- a/detox/test/android/app/build.gradle +++ b/detox/test/android/app/build.gradle @@ -4,7 +4,9 @@ apply plugin: 'kotlin-android' apply from: '../../../android/rninfo.gradle' react { - autolinkLibrariesWithApp() + if (rnInfo.isRN75OrHigher) { + autolinkLibrariesWithApp() + } } android { From cd0d6bb3eb88e3f3fd6a3669227e467d1c76b1d8 Mon Sep 17 00:00:00 2001 From: Georgy Steshin Date: Mon, 2 Dec 2024 10:50:29 +0200 Subject: [PATCH 05/24] Patch settings file to support rn < 75 --- detox/scripts/postinstall.js | 4 +- detox/scripts/updateGradle.js | 40 +++++++++++++++---- detox/test/android/app/build.gradle | 9 ----- detox/test/android/settings.gradle | 34 ++-------------- detox/test/scripts/postinstall.js | 4 +- .../demo-react-native/scripts/postinstall.js | 4 +- 6 files changed, 43 insertions(+), 52 deletions(-) diff --git a/detox/scripts/postinstall.js b/detox/scripts/postinstall.js index b03fbedd51..f1957898b4 100755 --- a/detox/scripts/postinstall.js +++ b/detox/scripts/postinstall.js @@ -1,6 +1,6 @@ const { platform, env } = process; -const { setGradleVersionByRNVersion } = require('./updateGradle'); +const { patchGradleByRNVersion } = require('./updateGradle'); const isDarwin = platform === 'darwin'; const shouldInstallDetox = !env.DETOX_DISABLE_POSTINSTALL; @@ -12,4 +12,4 @@ if (isDarwin && shouldInstallDetox) { execFileSync(`${__dirname}/build_local_xcuitest.ios.sh`, { stdio: 'inherit' }); } -setGradleVersionByRNVersion(); +patchGradleByRNVersion(); diff --git a/detox/scripts/updateGradle.js b/detox/scripts/updateGradle.js index ed941871bd..ac401c2721 100644 --- a/detox/scripts/updateGradle.js +++ b/detox/scripts/updateGradle.js @@ -21,17 +21,43 @@ function getGradleVersionByRNVersion() { /** * Update the Gradle wrapper to the version that matches the React Native version. */ -function setGradleVersionByRNVersion() { - const gradleVersion = getGradleVersionByRNVersion(); - updateGradleWrapperSync(gradleVersion); +function patchGradleByRNVersion() { + updateGradleWrapperSync(); + patchSettingsGradle(); +} + +/** + * In RN75 and above the settings.gradle file should contain the following lines. We can't wrap them in 'if' statement + * because they should be the first line in the settings file. This patch could be safely removed after dropping support + * for RN74. + */ +function patchSettingsGradle() { + if (parseInt(rnMinor) >= 75) { + return; + } + + const settingsGradlePath = path.join(process.cwd(), 'android', 'settings.gradle'); + console.log(`Patching settings.gradle. File: ${settingsGradlePath}`); + + try { + let data = fs.readFileSync(settingsGradlePath, 'utf8'); + let updatedData = data.replace('pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") }', ''); + updatedData = updatedData.replace('plugins { id("com.facebook.react.settings") }', ''); + updatedData = updatedData.replace('extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() }', ''); + + fs.writeFileSync(settingsGradlePath, updatedData, 'utf8'); + console.log('settings.gradle patched successfully.'); + } catch (err) { + console.error('Error:', err); + } } /** * Update the Gradle wrapper to the specified version. - * - * @param {string} newVersion - the new Gradle wrapper version */ -function updateGradleWrapperSync(newVersion) { +function updateGradleWrapperSync() { + const newVersion = getGradleVersionByRNVersion(); + const gradleWrapperPath = path.join(process.cwd(), 'android', 'gradle', 'wrapper', 'gradle-wrapper.properties'); console.log(`Updating Gradle wrapper to version$ {newVersion}. File: ${gradleWrapperPath}`); @@ -47,5 +73,5 @@ function updateGradleWrapperSync(newVersion) { } module.exports = { - setGradleVersionByRNVersion + patchGradleByRNVersion: patchGradleByRNVersion }; diff --git a/detox/test/android/app/build.gradle b/detox/test/android/app/build.gradle index b5626f7dcc..d06c3adef7 100644 --- a/detox/test/android/app/build.gradle +++ b/detox/test/android/app/build.gradle @@ -105,15 +105,6 @@ dependencies { implementation "androidx.appcompat:appcompat:${rootProject.ext.appCompatVersion}" implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' - implementation project(path: ':@react-native-community_slider') - implementation project(':AsyncStorage') - implementation project(':react-native-webview') - implementation project(':react-native-community-checkbox') - implementation project(':react-native-community-geolocation') - implementation project(':react-native-datetimepicker') - implementation project(':react-native-launcharguments') - implementation project(':react-native-permissions') - androidTestImplementation(project(path: ':detox')) androidTestImplementation 'com.github.wix-incubator:detox-butler:1.0.4' } diff --git a/detox/test/android/settings.gradle b/detox/test/android/settings.gradle index 44240401b6..309069f5f2 100644 --- a/detox/test/android/settings.gradle +++ b/detox/test/android/settings.gradle @@ -1,13 +1,11 @@ +pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") } +plugins { id("com.facebook.react.settings") } +extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() } + apply from: file("../../android/rninfo.gradle") println "[settings] RNInfo: detected React Native version: (major=${ext.rnInfo.version})" -if (ext.rnInfo.isRN75OrHigher) { - pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") } - plugins { id("com.facebook.react.settings") } - extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() } -} - if (ext.rnInfo.isRN72OrHigher) { includeBuild('../node_modules/@react-native/gradle-plugin') } else { @@ -18,27 +16,3 @@ include ':app' include ':detox' project(':detox').projectDir = new File(rootProject.projectDir, '../../android/detox') - -include ':AsyncStorage' -project(':AsyncStorage').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-async-storage/async-storage/android') - -include ':react-native-webview' -project(':react-native-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview/android') - -include ':react-native-community-checkbox' -project(':react-native-community-checkbox').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/checkbox/android') - -include ':react-native-community-geolocation' -project(':react-native-community-geolocation').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/geolocation/android') - -include ':@react-native-community_slider' -project(':@react-native-community_slider').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/slider/android') - -include ':react-native-datetimepicker' -project(':react-native-datetimepicker').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/datetimepicker/android') - -include ':react-native-launcharguments' -project(':react-native-launcharguments').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-launch-arguments/android') - -include ':react-native-permissions' -project(':react-native-permissions').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-permissions/android') diff --git a/detox/test/scripts/postinstall.js b/detox/test/scripts/postinstall.js index c4df647ef1..f4bf7aa949 100644 --- a/detox/test/scripts/postinstall.js +++ b/detox/test/scripts/postinstall.js @@ -1,6 +1,6 @@ const fs = require('fs-extra'); const cp = require('child_process'); -const { setGradleVersionByRNVersion } = require('../../scripts/updateGradle'); +const { patchGradleByRNVersion } = require('../../scripts/updateGradle'); const patchBoostPodspec = () => { const log = message => console.log(`[POST-INSTALL] ${message}`); @@ -39,5 +39,5 @@ function podInstallIfRequired() { console.log('[POST-INSTALL] Running Detox\'s test-app post-install script...'); podInstallIfRequired(); -setGradleVersionByRNVersion() +patchGradleByRNVersion() console.log('[POST-INSTALL] Completed!'); diff --git a/examples/demo-react-native/scripts/postinstall.js b/examples/demo-react-native/scripts/postinstall.js index bf34bab72c..608b656bc3 100644 --- a/examples/demo-react-native/scripts/postinstall.js +++ b/examples/demo-react-native/scripts/postinstall.js @@ -1,6 +1,6 @@ const fs = require('fs-extra'); const cp = require('child_process'); -const { setGradleVersionByRNVersion } = require('detox/scripts/updateGradle'); +const { patchGradleByRNVersion } = require('detox/scripts/updateGradle'); const patchBoostPodspec = () => { const log = message => console.log(`[POST-INSTALL] ${message}`); @@ -39,5 +39,5 @@ function podInstallIfRequired() { console.log('[POST-INSTALL] Running Detox\'s example-app post-install script...'); podInstallIfRequired(); -setGradleVersionByRNVersion(); +patchGradleByRNVersion(); console.log('[POST-INSTALL] Completed!'); From 375ab8f8d590b771568ec586a2f4d90013461e97 Mon Sep 17 00:00:00 2001 From: Georgy Steshin Date: Mon, 2 Dec 2024 10:56:23 +0200 Subject: [PATCH 06/24] Fixed support for rn75 --- detox/android/settings.gradle | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/detox/android/settings.gradle b/detox/android/settings.gradle index a73c8f0bca..c65d71c825 100644 --- a/detox/android/settings.gradle +++ b/detox/android/settings.gradle @@ -1,18 +1,16 @@ +pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") } +plugins { id("com.facebook.react.settings") } +extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() } + apply from: '../android/rninfo.gradle' include ':detox' println("RNInfo: rootDir=$rootDir") - println "[settings] RNInfo: detected React Native version: (major=${ext.rnInfo.version})" -if (ext.rnInfo.isRN75OrHigher) { - pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") } - plugins { id("com.facebook.react.settings") } - extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() } + +if (ext.rnInfo.isRN72OrHigher) { + includeBuild('../node_modules/@react-native/gradle-plugin') } else { - if (ext.rnInfo.isRN72OrHigher) { - includeBuild('../node_modules/@react-native/gradle-plugin') - } else { - includeBuild('../node_modules/react-native-gradle-plugin') - } + includeBuild('../node_modules/react-native-gradle-plugin') } From 897cabdbd18778cf16f595804f753a575b62c348 Mon Sep 17 00:00:00 2001 From: Georgy Steshin Date: Mon, 2 Dec 2024 14:10:41 +0200 Subject: [PATCH 07/24] Rename .java to .kt --- .../main/java/com/example/{DetoxRNHost.java => DetoxRNHost.kt} | 0 .../main/java/com/example/{MainActivity.java => MainActivity.kt} | 0 .../java/com/example/{MainApplication.java => MainApplication.kt} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename detox/test/android/app/src/main/java/com/example/{DetoxRNHost.java => DetoxRNHost.kt} (100%) rename detox/test/android/app/src/main/java/com/example/{MainActivity.java => MainActivity.kt} (100%) rename detox/test/android/app/src/main/java/com/example/{MainApplication.java => MainApplication.kt} (100%) diff --git a/detox/test/android/app/src/main/java/com/example/DetoxRNHost.java b/detox/test/android/app/src/main/java/com/example/DetoxRNHost.kt similarity index 100% rename from detox/test/android/app/src/main/java/com/example/DetoxRNHost.java rename to detox/test/android/app/src/main/java/com/example/DetoxRNHost.kt diff --git a/detox/test/android/app/src/main/java/com/example/MainActivity.java b/detox/test/android/app/src/main/java/com/example/MainActivity.kt similarity index 100% rename from detox/test/android/app/src/main/java/com/example/MainActivity.java rename to detox/test/android/app/src/main/java/com/example/MainActivity.kt diff --git a/detox/test/android/app/src/main/java/com/example/MainApplication.java b/detox/test/android/app/src/main/java/com/example/MainApplication.kt similarity index 100% rename from detox/test/android/app/src/main/java/com/example/MainApplication.java rename to detox/test/android/app/src/main/java/com/example/MainApplication.kt From ad00b90df9c7e8edf2c1eebfb12bf35211286691 Mon Sep 17 00:00:00 2001 From: Georgy Steshin Date: Mon, 2 Dec 2024 14:10:41 +0200 Subject: [PATCH 08/24] Implemented auto linking --- .../src/main/java/com/example/DetoxRNHost.kt | 45 ++++++------------- .../src/main/java/com/example/MainActivity.kt | 36 +++++++-------- .../main/java/com/example/MainApplication.kt | 31 +++++-------- .../android/app/build.gradle | 4 ++ .../demo-react-native/android/settings.gradle | 4 ++ 5 files changed, 52 insertions(+), 68 deletions(-) diff --git a/detox/test/android/app/src/main/java/com/example/DetoxRNHost.kt b/detox/test/android/app/src/main/java/com/example/DetoxRNHost.kt index 6cceef33bf..758919b7a8 100644 --- a/detox/test/android/app/src/main/java/com/example/DetoxRNHost.kt +++ b/detox/test/android/app/src/main/java/com/example/DetoxRNHost.kt @@ -1,40 +1,23 @@ -package com.example; +package com.example -import android.app.Application; +import android.app.Application +import com.facebook.react.PackageList +import com.facebook.react.ReactPackage +import com.facebook.react.defaults.DefaultReactNativeHost -import com.facebook.react.ReactPackage; -import com.facebook.react.defaults.DefaultReactNativeHost; +internal class DetoxRNHost(application: Application) : DefaultReactNativeHost(application) { -import java.util.List; - -class DetoxRNHost extends DefaultReactNativeHost { - protected DetoxRNHost(Application application) { - super(application); + override fun getUseDeveloperSupport(): Boolean { + return BuildConfig.DEBUG } - @Override - public boolean getUseDeveloperSupport() { - return BuildConfig.DEBUG; - } + override val isNewArchEnabled: Boolean + get() = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED - @Override - protected boolean isNewArchEnabled() { - return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; - } - - @Override - protected Boolean isHermesEnabled() { - return BuildConfig.IS_HERMES_ENABLED; - } + override val isHermesEnabled: Boolean + get() = BuildConfig.IS_HERMES_ENABLED - @Override - protected List getPackages() { - // Packages that cannot be autolinked yet can be added manually here, for example: - // packages.add(new MyReactNativePackage()); - // TurboModules must also be loaded here providing a valid TurboReactPackage implementation: - // packages.add(new TurboReactPackage() { ... }); - // If you have custom Fabric Components, their ViewManagers should also be loaded here - // inside a ReactPackage. - return ReactNativeAdapter.getManualLinkPackages(); + override fun getPackages(): List = PackageList(this).packages.apply { + add(NativeModulePackage()) } } diff --git a/detox/test/android/app/src/main/java/com/example/MainActivity.kt b/detox/test/android/app/src/main/java/com/example/MainActivity.kt index 1a0203a36d..9ee730d64a 100644 --- a/detox/test/android/app/src/main/java/com/example/MainActivity.kt +++ b/detox/test/android/app/src/main/java/com/example/MainActivity.kt @@ -1,29 +1,29 @@ -package com.example; +package com.example -import android.content.Intent; +import android.content.Intent +import com.facebook.react.ReactActivity +import com.facebook.react.ReactActivityDelegate +import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled +import com.facebook.react.defaults.DefaultReactActivityDelegate -import com.facebook.react.ReactActivity; -import com.facebook.react.ReactActivityDelegate; - -public class MainActivity extends ReactActivity { - @Override - public void onNewIntent(Intent intent) { - super.onNewIntent(intent); - setIntent(intent); +open class MainActivity : ReactActivity() { + override fun onNewIntent(intent: Intent) { + super.onNewIntent(intent) + setIntent(intent) } /** * Returns the name of the main component registered from JavaScript. * This is used to schedule rendering of the component. */ - @Override - protected String getMainComponentName() { - return "example"; + override fun getMainComponentName(): String { + return "example" } - public static class MainActivityDelegate extends ReactActivityDelegate { - public MainActivityDelegate(ReactActivity activity, String mainComponentName) { - super(activity, mainComponentName); - } - } + /** + * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate] + * which allows you to enable New Architecture with a single boolean flags [fabricEnabled] + */ + override fun createReactActivityDelegate(): ReactActivityDelegate = + DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled) } diff --git a/detox/test/android/app/src/main/java/com/example/MainApplication.kt b/detox/test/android/app/src/main/java/com/example/MainApplication.kt index ac7fdc0ed0..54ddd53148 100644 --- a/detox/test/android/app/src/main/java/com/example/MainApplication.kt +++ b/detox/test/android/app/src/main/java/com/example/MainApplication.kt @@ -1,25 +1,18 @@ -package com.example; +package com.example -import android.app.Application; -import android.webkit.WebView; +import android.app.Application +import android.webkit.WebView +import com.facebook.react.ReactApplication +import com.facebook.react.ReactNativeHost +import com.facebook.soloader.SoLoader -import com.facebook.react.ReactApplication; -import com.facebook.react.ReactNativeHost; -import com.facebook.soloader.SoLoader; +class MainApplication : Application(), ReactApplication { + override val reactNativeHost: ReactNativeHost = DetoxRNHost(this) -public class MainApplication extends Application implements ReactApplication { - private final ReactNativeHost mReactNativeHost = new DetoxRNHost(this); + override fun onCreate() { + super.onCreate() - @Override - public ReactNativeHost getReactNativeHost() { - return mReactNativeHost; - } - - @Override - public void onCreate() { - super.onCreate(); - - SoLoader.init(this, /* native exopackage */ false); - WebView.setWebContentsDebuggingEnabled(true); + SoLoader.init(this, /* native exopackage */false) + WebView.setWebContentsDebuggingEnabled(true) } } diff --git a/examples/demo-react-native/android/app/build.gradle b/examples/demo-react-native/android/app/build.gradle index a631b1604c..59249699cf 100644 --- a/examples/demo-react-native/android/app/build.gradle +++ b/examples/demo-react-native/android/app/build.gradle @@ -1,6 +1,10 @@ apply plugin: 'com.android.application' apply plugin: 'com.facebook.react' +react { + autolinkLibrariesWithApp() +} + android { namespace 'com.example' diff --git a/examples/demo-react-native/android/settings.gradle b/examples/demo-react-native/android/settings.gradle index fb6bbf47c1..565c01eea4 100644 --- a/examples/demo-react-native/android/settings.gradle +++ b/examples/demo-react-native/android/settings.gradle @@ -1,3 +1,7 @@ +pluginManagement { includeBuild("../../../node_modules/@react-native/gradle-plugin") } +plugins { id("com.facebook.react.settings") } +extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() } + apply from: '../../../detox/android/rninfo.gradle' rootProject.name = 'DetoxRNExample' From badd0e1138cedb83f686e0b498d719a8edcbe12c Mon Sep 17 00:00:00 2001 From: Georgy Steshin Date: Mon, 2 Dec 2024 14:35:27 +0200 Subject: [PATCH 09/24] Added support for auto linkage for rn 75 in demo project --- .../java/com/example/ReactNativeAdapter.java | 32 ------------------- detox/test/package.json | 22 ++++++------- .../android/app/build.gradle | 2 -- .../java/com/example/MainApplication.java | 6 ++-- .../demo-react-native/android/settings.gradle | 18 ++--------- .../ios/example.xcodeproj/project.pbxproj | 9 ++++-- examples/demo-react-native/package.json | 20 ++++++------ 7 files changed, 32 insertions(+), 77 deletions(-) delete mode 100644 detox/test/android/app/src/main/java/com/example/ReactNativeAdapter.java diff --git a/detox/test/android/app/src/main/java/com/example/ReactNativeAdapter.java b/detox/test/android/app/src/main/java/com/example/ReactNativeAdapter.java deleted file mode 100644 index fe61cee526..0000000000 --- a/detox/test/android/app/src/main/java/com/example/ReactNativeAdapter.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.example; - -import com.facebook.react.ReactPackage; -import com.facebook.react.shell.MainReactPackage; -import com.reactcommunity.rndatetimepicker.RNDateTimePickerPackage; -import com.reactnativecommunity.asyncstorage.AsyncStoragePackage; -import com.reactnativecommunity.checkbox.ReactCheckBoxPackage; -import com.reactnativecommunity.geolocation.GeolocationPackage; -import com.reactnativecommunity.slider.ReactSliderPackage; -import com.reactnativecommunity.webview.RNCWebViewPackage; -import com.reactnativelauncharguments.LaunchArgumentsPackage; -import com.zoontek.rnpermissions.RNPermissionsPackage; - -import java.util.Arrays; -import java.util.List; - -class ReactNativeAdapter { - public static List getManualLinkPackages() { - return Arrays.asList( - new MainReactPackage(), - new ReactSliderPackage(), - new GeolocationPackage(), - new RNCWebViewPackage(), - new NativeModulePackage(), - new AsyncStoragePackage(), - new ReactCheckBoxPackage(), - new RNDateTimePickerPackage(), - new LaunchArgumentsPackage(), - new RNPermissionsPackage() - ); - } -} diff --git a/detox/test/package.json b/detox/test/package.json index de42e7acf4..2c1499ef18 100644 --- a/detox/test/package.json +++ b/detox/test/package.json @@ -31,19 +31,19 @@ "verify-artifacts:android": "jest ./scripts/verify_artifacts_are_not_missing.android.test.js --testEnvironment node" }, "dependencies": { - "@react-native-async-storage/async-storage": "^1.17.3", - "@react-native-community/checkbox": "0.5.16", + "@react-native-async-storage/async-storage": "^2.1.0", + "@react-native-community/checkbox": "^0.5.17", "@react-native-community/datetimepicker": "^8.2.0", - "@react-native-community/geolocation": "^3.2.1", - "@react-native-community/slider": "4.5.0", - "@react-native-picker/picker": "^2.1.0", - "@react-native-segmented-control/segmented-control": "2.3.0", - "moment": "^2.24.0", + "@react-native-community/geolocation": "^3.4.0", + "@react-native-community/slider": "^4.5.5", + "@react-native-picker/picker": "^2.10.1", + "@react-native-segmented-control/segmented-control": "^2.5.6", + "moment": "^2.30.1", "react": "18.3.1", "react-native": "0.75.4", - "react-native-launch-arguments": "^4.0.0", - "react-native-permissions": "^4.0.2", - "react-native-webview": "^11.18.1", + "react-native-launch-arguments": "^4.0.2", + "react-native-permissions": "^5.2.1", + "react-native-webview": "^13.12.4", "ssim.js": "^3.5.0" }, "devDependencies": { @@ -57,7 +57,7 @@ "@tsconfig/react-native": "^3.0.0", "@types/jest": "^29.5.11", "@types/node": "^16.18.68", - "@types/react": "^18.2.6", + "@types/react": "^18.3.1", "@typescript-eslint/eslint-plugin": "^6.16.0", "@typescript-eslint/parser": "^6.16.0", "axios": "^1.7.7", diff --git a/examples/demo-react-native/android/app/build.gradle b/examples/demo-react-native/android/app/build.gradle index 59249699cf..38cd6180b4 100644 --- a/examples/demo-react-native/android/app/build.gradle +++ b/examples/demo-react-native/android/app/build.gradle @@ -75,8 +75,6 @@ dependencies { // Apply Hermes as the JS engine implementation 'com.facebook.react:hermes-android' - implementation(project(path: ':AsyncStorage')) // !!! Note: not required unless effectively used by your app - // noinspection GradleDynamicVersion androidTestImplementation 'com.wix:detox:+' androidTestImplementation 'com.linkedin.testbutler:test-butler-library:2.2.1' diff --git a/examples/demo-react-native/android/app/src/main/java/com/example/MainApplication.java b/examples/demo-react-native/android/app/src/main/java/com/example/MainApplication.java index 3b871d0dc9..a977bbac2a 100644 --- a/examples/demo-react-native/android/app/src/main/java/com/example/MainApplication.java +++ b/examples/demo-react-native/android/app/src/main/java/com/example/MainApplication.java @@ -2,6 +2,7 @@ import android.app.Application; +import com.facebook.react.PackageList; import com.facebook.react.ReactApplication; import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; @@ -21,10 +22,7 @@ public boolean getUseDeveloperSupport() { @Override protected List getPackages() { - return Arrays.asList( - new MainReactPackage(), - new AsyncStoragePackage() // Note: Not required unless effectively used by your app - ); + return new PackageList(this).getPackages(); } }; diff --git a/examples/demo-react-native/android/settings.gradle b/examples/demo-react-native/android/settings.gradle index 565c01eea4..813abd253e 100644 --- a/examples/demo-react-native/android/settings.gradle +++ b/examples/demo-react-native/android/settings.gradle @@ -1,20 +1,6 @@ -pluginManagement { includeBuild("../../../node_modules/@react-native/gradle-plugin") } +pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") } plugins { id("com.facebook.react.settings") } extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() } - -apply from: '../../../detox/android/rninfo.gradle' +includeBuild('../node_modules/@react-native/gradle-plugin') rootProject.name = 'DetoxRNExample' - include ':app' - -println("[settings] RNInfo: detected React Native version: (major=${ext.rnInfo.version})") - -if (ext.rnInfo.isRN72OrHigher) { - includeBuild('../node_modules/@react-native/gradle-plugin') -} else { - includeBuild('../node_modules/react-native-gradle-plugin') -} - - -include ':AsyncStorage' -project(':AsyncStorage').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-async-storage/async-storage/android') diff --git a/examples/demo-react-native/ios/example.xcodeproj/project.pbxproj b/examples/demo-react-native/ios/example.xcodeproj/project.pbxproj index f3afd347a6..bf8b29778b 100644 --- a/examples/demo-react-native/ios/example.xcodeproj/project.pbxproj +++ b/examples/demo-react-native/ios/example.xcodeproj/project.pbxproj @@ -228,12 +228,16 @@ inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-resources.sh", "${PODS_CONFIGURATION_BUILD_DIR}/RNCAsyncStorage/RNCAsyncStorage_resources.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/React-Core_privacy.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact/React-cxxreact_privacy.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/boost/boost_privacy.bundle", ); name = "[CP] Copy Pods Resources"; outputPaths = ( "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNCAsyncStorage_resources.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-Core_privacy.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-cxxreact_privacy.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/boost_privacy.bundle", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -385,6 +389,7 @@ OTHER_LDFLAGS = "$(inherited)"; REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG"; USE_HERMES = false; }; name = Debug; diff --git a/examples/demo-react-native/package.json b/examples/demo-react-native/package.json index 790b47d871..5f2a32ead2 100644 --- a/examples/demo-react-native/package.json +++ b/examples/demo-react-native/package.json @@ -22,25 +22,25 @@ "clean:android": "pushd android && ./gradlew clean && popd" }, "dependencies": { - "@react-native-async-storage/async-storage": "^1.21.0", - "react": "18.2.0", - "react-native": "0.74.6", + "@react-native-async-storage/async-storage": "^2.1.0", + "react": "18.3.1", + "react-native": "0.75.4", "tslib": "^2.0.3" }, "devDependencies": { "@babel/preset-env": "^7.20.0", - "@react-native/babel-preset": "0.74.88", - "@react-native/eslint-config": "0.74.88", - "@react-native/metro-config": "0.74.88", - "@react-native/typescript-config": "0.74.88", - "@tsconfig/react-native": "^2.0.2", + "@react-native/babel-preset": "0.75.4", + "@react-native/eslint-config": "0.75.4", + "@react-native/metro-config": "0.75.4", + "@react-native/typescript-config": "0.75.4", + "@tsconfig/react-native": "^3.0.5", "@types/fs-extra": "^9.0.13", "@types/jest": "^29.2.1", - "@types/react": "^18.2.6", + "@types/react": "^18.3.1", "detox": "^20.28.0", "fs-extra": "^9.1.0", "jest": "^29.6.3", "ts-jest": "^29.0.3", - "typescript": "^5.0.4" + "typescript": "^5.3.3" } } From d88aa444bc2fc3c8ff8b1a1a768e123e49d736c4 Mon Sep 17 00:00:00 2001 From: Georgy Steshin Date: Mon, 2 Dec 2024 14:42:48 +0200 Subject: [PATCH 10/24] Fix auto linkage for rn < 75 --- detox/test/android/app/build.gradle | 5 +++++ detox/test/android/settings.gradle | 11 ++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/detox/test/android/app/build.gradle b/detox/test/android/app/build.gradle index d06c3adef7..464ead8b76 100644 --- a/detox/test/android/app/build.gradle +++ b/detox/test/android/app/build.gradle @@ -120,3 +120,8 @@ task copyDownloadableDepsToLibs(type: Copy) { from configurations.implementation into 'libs' } + +if (!ext.rnInfo.isRN75OrHigher) { + // For versions below 0.75, we need to apply the old plugin + apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) +} diff --git a/detox/test/android/settings.gradle b/detox/test/android/settings.gradle index 309069f5f2..a67506e750 100644 --- a/detox/test/android/settings.gradle +++ b/detox/test/android/settings.gradle @@ -3,16 +3,21 @@ plugins { id("com.facebook.react.settings") } extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() } apply from: file("../../android/rninfo.gradle") - println "[settings] RNInfo: detected React Native version: (major=${ext.rnInfo.version})" +if (!ext.rnInfo.isRN75OrHigher) { + // For versions below 0.75, we need to apply the old plugin + apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) +} + +rootProject.name = 'DetoxTest' +include ':app' + if (ext.rnInfo.isRN72OrHigher) { includeBuild('../node_modules/@react-native/gradle-plugin') } else { includeBuild('../node_modules/react-native-gradle-plugin') } -rootProject.name = 'DetoxTest' -include ':app' include ':detox' project(':detox').projectDir = new File(rootProject.projectDir, '../../android/detox') From 74f7069edc7ae756050a0468c78175955a9fe894 Mon Sep 17 00:00:00 2001 From: Georgy Steshin Date: Mon, 2 Dec 2024 15:20:18 +0200 Subject: [PATCH 11/24] Fixed android new arch --- .../android/app/src/main/java/com/example/MainApplication.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/detox/test/android/app/src/main/java/com/example/MainApplication.kt b/detox/test/android/app/src/main/java/com/example/MainApplication.kt index 54ddd53148..5dfdfae2ec 100644 --- a/detox/test/android/app/src/main/java/com/example/MainApplication.kt +++ b/detox/test/android/app/src/main/java/com/example/MainApplication.kt @@ -4,6 +4,7 @@ import android.app.Application import android.webkit.WebView import com.facebook.react.ReactApplication import com.facebook.react.ReactNativeHost +import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load import com.facebook.soloader.SoLoader class MainApplication : Application(), ReactApplication { @@ -14,5 +15,9 @@ class MainApplication : Application(), ReactApplication { SoLoader.init(this, /* native exopackage */false) WebView.setWebContentsDebuggingEnabled(true) + if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { + // If you opted-in for the New Architecture, we load the native entry point for this app. + load() + } } } From 11c201687f1a4f629fffc3ea1e320336688dec82 Mon Sep 17 00:00:00 2001 From: Georgy Steshin Date: Mon, 2 Dec 2024 15:20:27 +0200 Subject: [PATCH 12/24] TMP log --- detox/test/e2e/06.device.view-hierarchy.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/detox/test/e2e/06.device.view-hierarchy.test.js b/detox/test/e2e/06.device.view-hierarchy.test.js index 7b72381676..0e52629021 100644 --- a/detox/test/e2e/06.device.view-hierarchy.test.js +++ b/detox/test/e2e/06.device.view-hierarchy.test.js @@ -26,6 +26,7 @@ describe('generate view hierarchy', () => { it('generateViewHierarchyXml() - should generate xml for web view', async () => { await element(by.text('WebView')).tap(); const hierarchy = await device.generateViewHierarchyXml(); + console.log(hierarchy); await expectViewHierarchySnapshotToMatch(hierarchy, `view-hierarchy-web-view`); }); From 5691846efea49937765fb454095d5d95ceb9eebc Mon Sep 17 00:00:00 2001 From: Georgy Steshin Date: Mon, 2 Dec 2024 18:27:19 +0200 Subject: [PATCH 13/24] Support rnwebview >=13.0.0 --- .../espresso/web/DetoxWebAtomMatcher.java | 4 ++- .../detox/espresso/web/WebViewElement.java | 29 +++++++++++++++++-- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/detox/android/detox/src/full/java/com/wix/detox/espresso/web/DetoxWebAtomMatcher.java b/detox/android/detox/src/full/java/com/wix/detox/espresso/web/DetoxWebAtomMatcher.java index 8ccd21138a..0148505376 100644 --- a/detox/android/detox/src/full/java/com/wix/detox/espresso/web/DetoxWebAtomMatcher.java +++ b/detox/android/detox/src/full/java/com/wix/detox/espresso/web/DetoxWebAtomMatcher.java @@ -9,6 +9,8 @@ import static androidx.test.espresso.web.webdriver.DriverAtoms.findMultipleElements; +import android.os.Debug; + public class DetoxWebAtomMatcher { private DetoxWebAtomMatcher() { @@ -46,4 +48,4 @@ public static Atom> matcherForPartialLinkText(String part public static Atom> matcherForTagName(String tag) { return findMultipleElements(Locator.TAG_NAME, tag); } -} \ No newline at end of file +} diff --git a/detox/android/detox/src/full/java/com/wix/detox/espresso/web/WebViewElement.java b/detox/android/detox/src/full/java/com/wix/detox/espresso/web/WebViewElement.java index 778037a30a..c89d81448c 100644 --- a/detox/android/detox/src/full/java/com/wix/detox/espresso/web/WebViewElement.java +++ b/detox/android/detox/src/full/java/com/wix/detox/espresso/web/WebViewElement.java @@ -1,5 +1,6 @@ package com.wix.detox.espresso.web; +import android.os.Debug; import android.view.View; import android.webkit.WebView; @@ -7,8 +8,11 @@ import androidx.test.espresso.web.model.ElementReference; import androidx.test.espresso.web.sugar.Web; +import org.hamcrest.BaseMatcher; import org.hamcrest.CoreMatchers; +import org.hamcrest.Description; import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeMatcher; import java.util.List; @@ -20,11 +24,30 @@ public class WebViewElement { - final Matcher matcher; final Web.WebInteraction webViewInteraction; - WebViewElement(@Nullable Matcher matcher) { - this.matcher = matcher != null ? matcher : allOf(CoreMatchers.instanceOf(WebView.class), isDisplayed()); + WebViewElement(@Nullable Matcher userMatcher) { + Matcher matcher = null; + + if (userMatcher != null) { + matcher = new TypeSafeMatcher<>() { + + @Override + protected boolean matchesSafely(View item) { + // Support for react-native-webview >= 13.0.0 + if (item instanceof WebView && item.getParent().getClass().getSimpleName().equals("RNCWebViewWrapper")) { + return userMatcher.matches(item.getParent()); + } + + return userMatcher.matches(item); + } + + @Override + public void describeTo(Description description) { + userMatcher.describeTo(description); + } + }; + } this.webViewInteraction = matcher != null ? onWebView(matcher) : onWebView(); } From f122f0b7552c482b23ca0b941f21b35b846186be Mon Sep 17 00:00:00 2001 From: Georgy Steshin Date: Tue, 3 Dec 2024 12:03:18 +0200 Subject: [PATCH 14/24] Support rnwebview >=13.0.0 --- .../espresso/web/DetoxWebAtomMatcher.java | 6 ++---- .../wix/detox/espresso/web/WebElement.java | 1 - .../detox/espresso/web/WebViewElement.java | 14 +++++++------- .../assets/scroll-to-view-webview.android.png | Bin 10292 -> 27403 bytes 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/detox/android/detox/src/full/java/com/wix/detox/espresso/web/DetoxWebAtomMatcher.java b/detox/android/detox/src/full/java/com/wix/detox/espresso/web/DetoxWebAtomMatcher.java index 0148505376..940ad50ddb 100644 --- a/detox/android/detox/src/full/java/com/wix/detox/espresso/web/DetoxWebAtomMatcher.java +++ b/detox/android/detox/src/full/java/com/wix/detox/espresso/web/DetoxWebAtomMatcher.java @@ -1,16 +1,14 @@ package com.wix.detox.espresso.web; +import static androidx.test.espresso.web.webdriver.DriverAtoms.findMultipleElements; + import androidx.test.espresso.web.model.Atom; import androidx.test.espresso.web.model.ElementReference; import androidx.test.espresso.web.webdriver.Locator; import java.util.List; -import static androidx.test.espresso.web.webdriver.DriverAtoms.findMultipleElements; - -import android.os.Debug; - public class DetoxWebAtomMatcher { private DetoxWebAtomMatcher() { diff --git a/detox/android/detox/src/full/java/com/wix/detox/espresso/web/WebElement.java b/detox/android/detox/src/full/java/com/wix/detox/espresso/web/WebElement.java index 695465d782..488f302d8d 100644 --- a/detox/android/detox/src/full/java/com/wix/detox/espresso/web/WebElement.java +++ b/detox/android/detox/src/full/java/com/wix/detox/espresso/web/WebElement.java @@ -3,7 +3,6 @@ import androidx.test.espresso.web.model.Atom; import androidx.test.espresso.web.model.Atoms; import androidx.test.espresso.web.model.ElementReference; -import androidx.test.espresso.web.model.Evaluation; import androidx.test.espresso.web.model.SimpleAtom; import androidx.test.espresso.web.sugar.Web; import androidx.test.espresso.web.webdriver.DriverAtoms; diff --git a/detox/android/detox/src/full/java/com/wix/detox/espresso/web/WebViewElement.java b/detox/android/detox/src/full/java/com/wix/detox/espresso/web/WebViewElement.java index c89d81448c..641a5011fe 100644 --- a/detox/android/detox/src/full/java/com/wix/detox/espresso/web/WebViewElement.java +++ b/detox/android/detox/src/full/java/com/wix/detox/espresso/web/WebViewElement.java @@ -1,6 +1,7 @@ package com.wix.detox.espresso.web; -import android.os.Debug; +import static androidx.test.espresso.web.sugar.Web.onWebView; + import android.view.View; import android.webkit.WebView; @@ -8,8 +9,6 @@ import androidx.test.espresso.web.model.ElementReference; import androidx.test.espresso.web.sugar.Web; -import org.hamcrest.BaseMatcher; -import org.hamcrest.CoreMatchers; import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.TypeSafeMatcher; @@ -18,10 +17,6 @@ import javax.annotation.Nullable; -import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; -import static androidx.test.espresso.web.sugar.Web.onWebView; -import static org.hamcrest.CoreMatchers.allOf; - public class WebViewElement { final Web.WebInteraction webViewInteraction; @@ -39,6 +34,11 @@ protected boolean matchesSafely(View item) { return userMatcher.matches(item.getParent()); } + if (item.getClass().getSimpleName().equals("RNCWebViewWrapper")) { + // We never want to match the wrapper of the webview + return false; + } + return userMatcher.matches(item); } diff --git a/detox/test/e2e/assets/scroll-to-view-webview.android.png b/detox/test/e2e/assets/scroll-to-view-webview.android.png index 380e92f3064c20201ce31f81606abee9b254e726..733d59615bb32d6bf4616a62de4abd5c9d553534 100644 GIT binary patch literal 27403 zcmeFaXyhrYPo~dyT)6G__65y)-o! zBv%v^T3pJFTo4rj({KU7Pyq#j`|@|6|D$uBoY(6-I(I$rD~fP^ujO;Sw~HQKwX>1g zp}0dzN=oM9h4a^>q<%4$lG=Xgx9#939o<1Q;IbwBn$20M+5zPS@Zgv5vlp-b2L8qW zb_*dT^_SGe^JlK#Em#~oBO~?KAMgKpkDojDi){THr+0i_U*A^n7r&X|w}Fe4mx40* zdb;St7I69g^TE$P_&E=Lu7#iV;Ac(zxi9?O4u3*|pRnjBH2evVe^P{>%;+aG`pJxb zGNYf&=qEG!$&7w7qo2&^Co}rVjQ-y+BTpXtRANJ`SWOcC^2>qJ6V0!?ZYi3bJNx*pVxRlgqp4Cj9SdWpR{_65r)C*kO&zk5u1!H<3S_kBD*$M0qu8MV>oJeOek ze4!{7zr-iAFbZ>R1ZFH`4pSRmxMGa@6}TU9TXzGf_Vez>3K-=OlTO0kl9wUxAn(9j4ORGPWT@njUCvhiWav|-+ zn058EH_}p1GD%)(FU_$l%ilf?#~6M!3;6J~6))2Et}HXP#Bq^DwF;}ccyVOM{9vJ) zJalr{V4IX;6B$mQ8Tv-JornFR+(>zDZ+(jAx{gr_S)^iC zw_C}DuG8tv+Ln^=KYjs{)y(E|?rkA5XPGI*EhTT;aie0;=vNk^A7Rg9f?Mh8qpqd# zlsOAhd*p)5Y`$)K2gDCeQGd9bMHQS5X&Ab6be_3(clr_4O-D+q{rMT|%LQ@pj=tRf zkhs1RbY@W^X5Cb~>G}#e3jOPTgz?N{gl-~71aacgEWK$7akXCN3-hIpq(WwGT=aN( zzIDN!vjpPrpar^ecV4XhNXe%~b?)oU32F81sP8p|!r`M{X8jw>KR(GlKT;9kUCq0a z^pE%Xjx3jQ(TT)(fyBur{eb@43K)oleKq>c_@)2D-RWx`M`AJi+q>W2m#an6EB$Km%q z;k}T6GDN3*$P#m22i2bKMY^n8mf*5C;18B;f~GeZ*KF4kA!8^%GtJ(za6sEDPMcMF zDCe=zd969bjAK;t)lez2_K|Kk9~4Ov61c=@ z|G+rVRaWxpYx6c5&TeI`GyO~yKF;n$OjvCHPMrfMf?Q+!eY)NdAoec}wWsU4)xGW> zoK81Vr^Xy1`hGbyJU6YOw$SRcxW-vPi^_7YnajKW#cGh#7>WbkYVN2z@3LcpQIeLb zF4~Ke)X}q7X4m1E%8hm0YS}a`W_#O>1M zdI=|Uw)c2y$=%h#lC^KLY2K_R82%xm#5Jg{WGrr}q(#6ed3mC=X)c&p*PTt`yl`~a zG9rl_d?y-9TE0Ik8H1rp4xA`qk{WxCS#c~Sj(a5n7kknvVrflAMX^|nkDGs8V$673 za=@U92lMcLRAM~;s-$JED8^$+TJ=IC)Hh4O=ZpA8;#2aTUnAGK7KW4vY7W_h?_*wMCtJNBea({r$i;z!_{XuMXcjM1VX5`|AR zooyEcGErDJUA(6kde|;bLc5ZCZEw=rIftNTHxdfA(w{cnwvsyCZ!~wMFpkmU8kxu` zRcjX-h0pHoEX#4mOVos}B7#v|l*44Gje~O71&5lpFcKEz!k$ssMTHU0Vnk?_+^^9wsx4cbpk-QD1n zjD>dBCe@f)Y?swZ)f>2Q zjX5~Iuak(E#Qo_;`#bYshF<7{=TfKp^m;S*Y~I5Ic|(4oieb$F)a@v%{`FEB-SR0sx_k~ zD%VApVYdWGnBnbXJB_Jvr*LycC1W>|XEO}&8@>*0D|X>r2Dnoby>@o&zug&`+RYcX zD1J>G9Nsq%i}iTVnX@$FZxd0wzoi%@s!t5uo0$wB&b+RLy2+low{4aJX?CAbxU>2| z#PQ-&ToS{E`+UaUMN~8#8QEd1nxOyS60)t?p>$$64^+H}Yo1Xqb%Win&RB68iiy$J z$fT_qMH87SpkLzHxjoeaPs3%fL?VvF)?R#`>Mdk>=JKYZ)v(^% z$wF6*?(t=M{BG>*p%|cgLgK7(Nj}|N- zNicG7ezgno-VD*j!*aI{HYkwzd!x&0#IJ%p>fSpWJT%KJz<92pi$SctH)Dhkput`W z$KY5t{%wfM`#~38x2F+pGFHlkx3*G@l{8(4Tu=q8>9H!Mh-46d*I_a)WF@k|P}?9p zgfFHh@JsG8krM<;4(OA~|Mp3-&@)bFbk4%g!o-}`t1I7mIKL4;$-cJl&SJBNfD%Mv z3V7)Jkk>;V8JjamxCGrBx9C6%9|#V!ask3;-#S)^Y?Up@6h`g-`cj5)1Ngo5?Auu zw%abkgfnccMl;1w=A)CZkfmWb{8`)&43k|G{ zfx@$jsF_?08?#J@)ySQQ3hEfTToH>C1S%d_&h`k*;j=<)g4#kmqVXPLiqZ*n?=%*<{hqvYjXER2gi&ra_>6dj?>K4iu8aN+h%RlHygfxT_{4Ip~ zO3*7#eMEkbmYhd$R$_5g4cco$UQKXS@t+kWdPu4`n&Koh zV!e5;ZXxC%%=tC=BDn=DnqVO(+3;uKmCOtQ932uD>m6YUrB&zKD2)Mf(kdgaDhy7a zUV4@X4{H$@B{=07;lPdZ={mnye_60JomL@QVN}ayS}2Bod$3^UHQP)c3Y~5oW}tj> z1BTUiTePe!A3Qfy=Qr|pwe{r*4H-tv@RbGZReCd79e`#;!$6?O)4v+olY^?iBnVb8 zS*C=)i(_Bxete8iRpL}btv05lk;LEcW)|7Gf<-m-Z|RIrD}Cs%+fK>YD+MnF?y_oL zkgkhIh)|TX#~s@O*S$VnFLD5E2rOLgQX-P^8)1P_Zm?p2bw#KOCuH-~Jiu1V-$(kI zYgCiB@9X5_T=vd%lXPZYr=)sUBdef<46~>ZHAyUXYdi~98N-ar-@uc?36YS|n<)lf zc=zay?J}3PEwuC8xjYmu592Tr*t5}4Y~Y0|x!@!JBFhNw8BXu-4T~cu)&zbSPG`j9rNAG!j7%BB3)^O$WIRvBggF!>C9*>Q-fj9;Od?lR?N?S&BL_L| zji$Qo4Z%Yo1GjjpW^ixj%Xu_7$4R#y{7Dk~qmYp1g@)i{yYUT$Q! zdvMbTv8t-+(@5pQ3VJfEskfCkAz(TYH%CY!a+Dvcr*TcfhvxiJRI1R>pt=#R?Cs3| z*?*1KrUbGDnWwIq_x8*Wa`{?tgDK;czGYU5%;kjV%*eSyqUC!f_*jDcd*pWIgy1BA z>|<2+d$rWvpY|I#o{CCp7c|f^+>SAbPMQF|EePFFWO#Lg!`SD$$^c_=FY*;(`iA6> z34Efe{r3SgrY@}3b87~*MGd>dINQq^YNT=L6H^U9G1`W@0G4z^kAULZH zs}H3o*RFQWc)QHWLnW~y`NE|pS|XjUa_97nZ-4G{_s*;=bmx9<&Pu786MjIC5Y*-c zmf~)c3AsB#EjPm(?i7UE#l-k@8}bvKo8lEtwTPYdo3>_vy?et|FCkVDT2s{*i+2P+ zqGwkxVMSh!70&q41YSVR@mKCvOBV$Hn)48AgPB#r_s-*?-TD@%b8Xau+r1#U23pf0 zNm@{}h?ky&p2?_Ox|=Ip3TbO&kCJ%Z&+W@?Y(R;N|F#qS_Qyv#A5hhUvCuXfToj!-U}@>SI^V@?nhXmdpOiiIq-%8n z7B-n_xqeYm>y<-(h?j8eWZ?A<`=p7xmOO*ex2p25jg-?eEiKa5zrJ-SRUfdx#)>2& zD9QJGl;@;hzCQf@lY{BOE_>y2pk6q(2Q9Eob=&sqnc-nT0T`|TZ@s!8S5fSRgG)ri zEz0Tcft84GLU24bHeE5R>w~LbZWkJ9nxPVNYi7y+e8+%U1?Pfk-U$uBrWAEirD_|m zI6nPTALRUta=SiiI>L69#X|1h?6{<5(A@vzAblqF{B^wU=^3!8r--KI`(@tf-??EL zb5wXUmN!1iBxZeiUM>Bt+W(LD8Gzw?V_7}YA@Q@hUA;^=ShsyI6QOG98w*#CoovPJCQi*cyP*2l$Vej`i4+_{Eoz?P3pp(|Nv+$Oi z9bR!(VE)WSg8Sl)zdA!C&qaBjT6m-XGN`oNP8&svUn%>iLV;QHeETTdc%I&uE2rD` zN8QG96B@rhyBe(`qpBR*A=ghlTGDzI>(#AB^K6lOx_$PzuqI2U%`@}$xnYyeT>mI9 zexDvvMNPNm6^~z@-6@}GJo|E)_E`yjp}U|eKL#=$zp~m2>k=??bdxqX`cK$jU-xJ2 zY`gq^FvTF8V@BGc^+Gp^OPuYkA${EGg38ygms{>%ZVc=9IY`+L4tEoxub`(n{ zsV8$h>*LqM31tp!rQpsHyY!6jw85{h7q+%6o)-$3FllA`Q*xnS4$+x;tsWDDuT!$2 zFKO}Nf%kvZWj2YG+t1VrImv24I6Ei&7P+HuZaX_&&Uv&aU$+6W-}7A)OV;%5sVN}G z=zCm1?xap;q(L5RcY3%xSi)5P=P$}dUD(3fs0Sn@X(pZC%cr1Qv)z`slqKtpMSo{oiWUua$AR{t&u++oSVc{sxh7|bV^itb% zyTh?P6&A!;1*d55kamN}n^l-k9tQM9XAgrU^lE$8d7Oe}5s|Ve}BPf-k?i zuWM?)G_M_d(uJ7mPi$LZ@j7+0buHJX5SHQ-lmv$TV&?2VD|^zbNLZ}`Kq+(d=ZCFM zaj$cuqG=FZ{9GZ~5rsfNqK-nn4B)mIf|PrP+&xVB~x>>k@Didv7kV7{$2J7)S3z{p4^)nj}ktEZUUK8i%o z??sYJT=*+U7bse+JdqcTx^7gm5AKU}omaS%L_pShaF0ev|`+oDe=&sO*@CaeXh4aL_(0p_56R>> z|FHS5%L=>HV@VHU8WwF79SruL(c2cm&zYI7aSJ$AX}R%QSn;w}@t20cd!sl;E#P9U zKzTOzK}J^G-!}ZdDASS}Lm8>0K-F$gncLD+7J6|%9;|-ySb8f0?M-2V9gB%n)Ch3k>LYSrJyH%QViI)E>9<;-x#^R z(w{T$C3}VR8)($F8%{H-HJWL-x?r`Kzpo58Z!F8jEkP_W32;G=_@#yUmFl%D)SG~v zmB_%Zl-`8ZEzTJf8-7N2+ zL|2HCKKyD9c^-pej0KMVIiLTF@~xZVb&Y1Ksm$Moa8JcdZ*p+8&3E1K0h0hs=N`My zl7A2KMJM8-IxK|e3!>b)v>GhDqprLBpScgxj(e7XfEuZt%C{6SAQk*7Q@Lu4kEcQ8 zV%tk(2}9?$lS-JkCXEu^}Knqc!<) z)TG3B_#N-ClhM{N#nN4Gi-!-_H%x{t)X@?b{sUU5!NyxoFD2P0KTlVKwzI&7W~2Oc zyUYeFL}}+QvDM1_?p%Lsz~9y}!Of4>sQjV52`u*3Ck<8QjZV?!Rd$omyRXf;F{m7` zz?$7Ab!q|Ui4R6nEGN0P#v*#l8Y;<3ISQBoSuPpI?3TS#(cPW?L{7u8pv9esucWR` zkb1Vgdmx{&#>vzGb>Dl?3X6xYTp}JY7L{rJxoWg^cRlZetTh03vC0uwF=z+$f0g>v-!RXSsHUKN{`Tdo!u+$61V?%PbK0RRm{$jKKFC$<{?NjyVwL?oKr7 z8(zj@Ty6866P90+ub27$cWG#KBjlRUOx^BIlkiR68ShSJHK!RfYuN4YY6aqK86MdM zXkYZXtpM41#`xwXAa!%iv8JaClXt9M!My!iu}k^oc0aS#uOq47{@q#SuLkyU#)6tK zmD*xiWgQ^dnA1pH`-BVq(^B`;+Ku()DmSHvyDE!f8w->BveRwVo-&%&rde@CMVpi0 zNbzwfZsgkkZqR0>2=`f?-`f}+U46f5#viIO#swNSP&1Yz=ZeVukLd_~?j5I`k1;2* z|NOcFN{E}<+UX9}xHk?HIbN8J5TFCFk&gBZZQ)E+bx)33#MPyOkIhDR=L!)(IEA7& zmWkxxmYeI#DXM|(c95*5FNYyUUkDFG7ur>0-o&qWTR6vI#bKUptmb7pz*K}^Vw}Fw zX%ecD{}@o4N0w_!2?;vW&x;quf{2vRnVy`GcV{~O-5C`ExySz2_{bupEK5DZv?`v` zZxkH@iA^q=R13iuZa=Q27q!@yz%DxJZ^!hVjE1hOyan2OA>kMk>4Mvkh*4bANGE3} z%_kbdr?GpjI`+A|KzaD2GgzBT_P#Wr{Y}m=x}gx_88L{696bu<^YKQ|Vk%?M2G}-j zp)fjcwz4Lqy(vBhDia~KMY_EYtZSWpDr#{{6!+HRbz3kH&ymy;6f5(~^IoBs%_`*s zPN(f1_awaKb^LmTB}B+(S6DdVHkNzIdcV?F2o-L-s~Dp$W0@l}-%>QdCJ_%omPs`1L4NZA9b49I9`7NM)yjHgpmnaOKpzkGH@4U)xG%NjonWE z0G}f8zdsjX-f6$P=Cq|`VWZ{S!_o4SNX2NNfk%*#Xa-DJ>I{2G@`B+etNaMrnkP_M5<-) zkQ>AU9k2VNi&p@y&$&4rv9{>nn^PQWy+h3-bif1|OoKZWbKDz{L`T2zmSe213^9JO zp795U=&W^m>Cn_G7q`T9{kKq?neK|wUHy6gfF3$ly~;ky7fguX8oY98=)VsI{)!ef z08VCKi`?RoDG||@`LNGV5XfdmtT1`^F=*n)-vg$`{U}LE$4dJSrs(rbs`9pT3!@cL zq_$&5DWVIo0W;Kkuv+{(L7X@XHIk?Xc8I#bjS6x|NNt;f-lpy|%iQx+C&I&+JkHUY%EE-qVE%SpJgTdN0%vT3ox>94gj}NLN03fOP~gDjJ$ycu`M4#9Xvbt z^<2K$c>DS+gL92X#o`pCEkp~9P-Wg^L#x>>-L@yq+ImqzitlRWocf17TH`3}u<)_W z#@Tz@@|f3t2$*uhMaT9;EGsaCRt&~M`-DdjE&h|jbDrK0!TMteD z_{7{9oT`4Mx`i4WAT{8w*lzsN1#EMLZ;5d?Lub;7^7v$F8|C;r3G_ZAsOd%Be81(V zHk%xyZv3=r-0>?AHv^B3%8GJ@IK{ffdU|gNrm`+<*0URU)q^M5hXSLqmbvl4B1VPuHywxdCdHHWt)Si@i4zx90|`T|L{QHlBhLmWL`c z%%f-t(L2spcPTAg1f{{ewihRKCX5mXH;qMSVtsIJePyN+my4?K32DFi1rS=A(2L=H z-ESuSLHAeE@5b|yfN+bxX18uEug*jam=IU;2;7YoIUBV?JJ;UCTiqE*i*d#kFpt+h z%J*O?=igw@01eeoT{FLj-9#F~Aki6PktBpXbWyP0)3flqp1(ENn0IK4IhhRHSIN44 zhn&s%pgJqA%9u~a(U5Bp`ixqp@xq(sNIo^c>o@S-guMKo!*BThg^^YH{gUrT=)V$%YtC zzx%|9qk?igc_W!IdMui%z&wgX)0haXX26r=^>FeE-;aIEkb)zI_n0_>7q zw4SugC7&n2#R>a9%0JCc0R?ke32NW{pCk#EBjEn$-0q7Mc+YlPfyoMmAV$c^sflhYqJg-) z7akF*QC3<}6lhCV0tq}~;AFtH9U7A5oaOL0eA8(JB9asgExhMd^$Mwj zd8;`T&@EK+fSZIAEtTi@6fa$d1|lbWb#-;4@gfE}u{6C0E$OyopguX;@9R8P{UT?W zF~i4)!14ObF`r&$XwOk@&R`C&+YBhqwb*8qI7Ru|-p!quT@a3$GY}CZFDxa8avGNs zl*}=jUFk4f#&Csvr-iUlveLk;wE|g^eiDqgSTc6!lb|@{>#HJdv=OVjqF6^4R@bSh zRZ$9{L9dEgb5odF>}~1`4^$4cmMZZG8pQFJD=dTCHWgB1)PQbkiDn`vjn_V4pM=re zZTu>pLc)!@wo~I9G@B=?%(;pdZJLI(ws^{;BT*2bKveg_i7d2y=hO#QOd;Ui4jXuh z3l6?%D38|EG99@l!E+`AJF_yMXbnS3V_OXn>)?2TK~zvotE~Bmd+X_vv>olE^MjQV zjt;gF)pscS!nUA9ZZ%7*0lQizI&u4Ihno0_pcd`@V@luo!=oeR*c#tF1^su0AQ6&& zmBxrD2C6{0bS>kESLTQ0;TwrZiapIgT`0{k)0y5_(EuU{?(zEU<)xeL{SRSH_vSOg z;+TnV4062kFsY4<@6R6JtP#LI69~D0|EvNI0fH8zJ*Ge2k934}tB@VhMPI?FpWSIy5b3P=TTln03r&k6 zBe3jCM_N`0#a%X<;a?8*6AXuUt8Luqu(5b%w>8texfO>`QB@3OB9RZ2!uu_g0!!kT z+5@WE{DQH;fhQA399Rp4Ha4bmJ+%GEE3Q{#U-f_QIp$mnjx6&!@ZN;G1+Q+^Jj6Ga z25On|KU0*M3E*zyM2fICH)cj0hxM`5weI3*dyDbAq^GaXX$)AHMLGq{nvW$(RtvrS z3%k%PJAmLAg2rLH^bl;vpGQAqXY*FEtAm-&DTmOLL-8uoyDm^J!Li8J&_~&>>IpgG zA1U#ezqcXvwoA8DH&$#G+rmvlvFo$?FDF2V$81~EF4Y3|wIF-~1H18BHqt&}t_f)1 zv&EL&7;2(WUm%H@BdQw1A04{3GaC|pC832DCkMtPBKSp1Ca>&e^866#k5j=qH6xF1adVhiS~uG00@r#6bR z4nS?avVvhX2ehR&5NcIk9B+0tZBAP6<)(AKdf-+-YUUj?BIXcmQm(hkSQ^V49q(l^zFg04~XELzQHmc?>hsXP}6OHvHdXE_#lYH zscj42LmwR)dX>IpUfDlhV6qTtA&M}4T_ALqcl(=S?sfA4yYO(M=Fr^SxW9&1q6x7= za|nVulw*s$nhj|d+Vxe~UeuVyFJBVyx9&WD9CN$s({gXc9tQO~+p|5`ayfC&;q%9v zuCHUN8eWsUF3Sh#wy(15B40na_E+=A9hC4bL}*5uWBK`0;=78<5$t=}Y1-MUTD7i{ zS4fug-UTxeh&$aGUl^vDM;!;k0Y~utd9SpL1*=hC$u?w#M_yVi6!f}I>=&4Ak(T|X)M-1vp zfeN2ckcoRUcyHUQ{XTau{M?y?U7sN?SBEs zAXnq8p874`P9cZb&qPM(M?d~eYE}lkwv>pf;D0_|FdPt7@7!0Q5W2ykGo#4b{V%q? zZ#y^zQg2W!s~HiJs3#KcgkBg%88N>aN1W4jz z0CGWCvI<>nZkFC!*KY_?gI;2zH0}MNlcB6iT`A&rUIaKZ^r~VJ8`1&5MC~CJ&}kiP ztj#WkKkK-oazOm7`~EC|q7?F`@&*cTF}+X$v+P#zKj69dmDz6~RX2~`z6-IoU_XrS zJ)40*04rGsXKbz*Ih!kIw)iz(B=xpf=NRZJ*v{jBgbrPl%kfeKE+FeD$RKHmmva!n z1G0~iin#I~L>cAkhV3e`J%l7`{MXHm;ATo0TN~_IRKb?3`J2NaPD;})+P+i8NN0Mv zR|6*?BEEgXQsHUZ>UJiF0Jt9tI;LUWC&X<1k+==)Y_XU>K|Ii-AA|)a!{zMF_nip! z?ii_*0|9fe5Hv+VP>`re98PzQ5Ehd-;9f^8ayecoVe!=u+BrfV^;D&&r)k ziAqWkRFR;Y`M!bP6q&RG7HvW%xWBJ$c@f0QT7ctp<}U3z}}S=gz7I!BUMgPOv_;@dMkN?V&S0 z0n^Ba;^r7&q@|EUR%L1?>=u5ClAPS82eJ0e+))ku;xj^6Y9 z%~_|aJuo$1o{&5DFanxz*!C{k0+c6!#~FI@cQ@59pd|D7ZO(g_l8Qm?>y>xc^!{>4 zBirpTh&Wy>_60o#bYPR@CXy?8qXw;yU9F{fe8B;R^p?xQ~A)5_I(;bCYKqaQ;J(CfR9e(*lsB>;K^-&8OgIFQh z3&Upn7Ft2{%@Un;TUIsxt@+DNfRvSN3AYg`9c77T6w+U*vvSS|zCjDB7#E5vSxs=Yfjk)2 zTehJwG!NhUj{+yMMJArSV<8E)8H{xD6V5U1gqh_ydl*cWWyt(l$ zpJs~;%H#0Jn-Z}_bpOK=IXM?d*4CV1JDB|x$Z#hV-Yf0EFs+Zb-I=3L8ky0YF{EK}u?_o(66?D}poO2x0+y3m{1eaXnb> z=!pB=pbgp4OQZbC<%9i$Hqn%4Io9Fi;@H5zx?$TJuCr)-`dB!j>s&@_ z@%SFQ+xF&u1GYDN>$-QCfcdZ0HKkbxN}U<|Kq$L)2`XM4UiddG%ZZ^2>v=JOl&;0< z7^H`sCqlkeWgqFE2*EGc{sC-vt|3j5xV~JL1K(H&7H9lALT-V*_W5bRsT3FJm8Hv0 zmva&Ne=K~EwwVmO%+G}V=+l!U2fJX?J_c4>0ZBmdYQ*aYLy1YeaRh$jP~^6wdT6W9 zD$)ArqQ;nC>0oP2-?T3GAT%;Ul$jyO?)iB%{FPS*`u6Meyob^sz} zBxHgkE>4V%GzWC5-Lk>YDa0}|@R-lH2i3i;%vu3cFVx%Nv4W%5z`L7P95QWG?A5jr z<^XP#Md;&_NG>^X>`EPOSsk1fr<`?Q-*2^6H#L^|zkZM3ape70NE_z33v zbQ);O)W0!~_+y)Ho7Dms7^JM>*elF~_xHBQF;T@{LSUFn`VZwqh)iH97oV%|wgeOv zgr@fY<^fkYA=x1M0{p^hLX~YXuC_qoMZuy-%*L|*z$Kec56ebPLA+8JcLJOzaIh(> z^>#{%o($zi%2o!()DM_0a1(hAa>?7Bz@+R6P=4xYcNA(Fa4pXqoL100GWGUd-$}aO zGtY#`KxePafZ?IlCy;LUso8ZFsHF!}UZAjx z^}PPE!7P$j_3mGG8~^p-gwxF{Hs>Cm2T692TlW^k zJR1aO#nWj_wL7aHclPE0H7nr#U@Wi@@+jqfP)T0b)k@##4#tng5l2Ut!q{C0o?ytE z=8pgbrH2mzOi}o|aUe*t4)m7WK3e1BnPhP-mVv#Boi7nc!`g)GWxA8LT^PR_nuV8z zm`vSUrUUJ)P7Cv?EGPTF0dmFv)DPC3224a)8q}5!98-SsTjwiV;=VsUdM{uEP^jZ| z=jZ5pe&@jf6cU+`m(^9P*#P1?B>!%e>I%17MQPt!|DvOk-M~QrF}t^)c5BfpfS6PM z4B!#dJ$FWaRN80hqA+h6Z)<$Jd~?d~|4n1I&M}I&a%c0+bUl(pBj%;Lf(cR{8UA2j zm2`3fr*oF+h;nPF!n(&xgy~IDcTraRE7?`o_9Zs;mZVw7i&qNOU`V1TV8G5PE?nDE zvzV|LSUCc~s=zjjm3~ruf>#_eemzyo&?^(M*V{=(apU98{wy%W359Og1J}m7hiar% zmey!@&UHlN9OKB*)P+fN-_K7X2J5?33o9(zIb9&5S`C?fb8(^7Y~p6h1eqRKjbtok zU-JW=>1JjD_)e!L7NC;UyHocEdglg822+t}oh8AwkPD+V#iAOKZ-%lPuB~Xn8=Ai$y2C2$Qn6r%*YBD|-Afy~Hng@*kF(|cM|IXLN zbGjnBn@4{gv6QS!nxf}EIFEAG-dpxm)gyk{^-SqTo?l7p;bq6kdn3P`ob>ZNs$~Gn zbMAdtq8xrwyZexTqk8zZbDs=I|M4sz3?)sT{%b_x^|ODT2!%6xyY3KHCga$xIXh)> zUV8qiOW{RxiAyGPrYmg(zHohnI%!+*vQxJEaixqgyzK-yhTu+Zz8bYH?&}%)+;z9O z z)N!qr19F@X(w!7XXUb&MQW5!jo>mpAuDs;yt?7(?LhfdmBh{M)uu-cO0-U)(Q+S}&!>8v5E9A1q0dOmKXAm&eBH-1y~1+PW+* z5w$-P`1KF-plfIMC$k>klaZ3Lc>Iepa-I~z?MXABM0u>IFFV>3qwXKDwD6vKPn4*d zHS^l?;m3-*ORPGLl7W_(xSQFXx=#+(?i?SKA8Z<}Q|QZ?Mu06JWZo>9$}L+8^_|PLSnG&|A#v-*YK0qi4%EhCy`;nr z-yFJzIvV|0;dwZyW$9=QzyNDt&UZ#`j=Tj-LA6>128QBwzd^|QSg8%WKZK1FrY1Q% zh|)u6Qgh}S60?3)PL_^lpBgQ5@%kc=2kG}vN+eTv(v{vavmEjr_&0IlXNT6KV*y~r zE~$b@y27Q688ueE4H~Wx1`c*irk8!5Y*qNPFydM*`+&LWbRNvKf(*D>knJzZk>DuH z^w}cWQ&-J+A9prU>~@>g+=YE?32pMx^V>_fIa)JOM~E+9YpsDwgiy}iIBZ3bCg``= zlf&i6rQDj}O!MWX?>sV@dVg+xP6GrLHaslpFQ$1Pxf8dZ2T=fLRJabjIPw5qB1Y&9 ze2&$&+_(wiQbrc?Qc`RG$lVzU*jSsW%hiMJ+`fO`4sBB-b-W0U+d4B~rm_FHYg`a} zGRRh0^#l_?LNr@Z|EXCG)tv^78sqjTV}RP(;+b~Yx689Qj@W?$xzAlQs*bd+Y!2BL~Z#{s-& zS|)vY1_TOq5JNbp1aOk?)(lgX_&cnzj}OMFkyk)uTG&>9_EmoHexRW=&G2b>9zM<8 zmfh^pVQ01vn!~M*UYh1urI|*ns<0^08i(z5s2M}p=#H`+YXG_*Djg{<*g|b4`^|%; zFC>ebi9f!Lw{9Z$XzG{Uhk+k|Ys#B3KK=9+$l~N`eog zDb1jYc5NL9Bp({y#H7?3HWwiG8sbvS!OirW~274{vUpPFWqa*Vdz=CxcTuRWDjM8GYreCM1<5mi@VT{c%hB-fC(Njw5 zhL8HxTSr2X!ZCgHZ1#(it*^UP$;**88GRuwB>e;dV{7u2E1g`UJb7*3PlHXc{b|RS zXY&iqax#`dT4aOa(%GFTBxj%dSH^)zZ248{Ui$rer7~a|M+J@65FvW-_9oui>y+mBey{dGY~^ui5pCZ3 z7CLp-$VDWeKZ`c>l<<=}XHe~Y4zk`+ z8&7QlcP3k(x6OO;>vj*l!0W-3hnqx~kdzvNkhN^Xt=Eh9Htoy!95PED&ec#S&_cV9 zPqoeh--!o7AM!npaB9YU%(WV@EeTI~{{AJp^ta$DG3@NBzT5WHpuICsIwtwGOWH(6X z0#k#vX0~)oYNY9dq&|!I%@ucw`EBn$9&51lu8#ew!7*iL1><+|;2iL2Z7t)8w{M$2 zYGj_@_$CX>1bzgF2Dl6wW-TS6n>FbNQ_csqM~X-g`5w4xjy7{LCg?LJDt&DzCpGg* z;RKFURRftnBW;k_Kl&n)|I$Fqo8Hq^8}sE*Ist&kG;+0$XG@fSY4b4{9SfENB(3M) zvW4M>CU|Mj$I{HiMhm_k-40_Cy$&dPm!u8e&JSq>|Wd?A^p4rsQ^FO5WSat6PCg|+tMo1C=TB#%ji%@w9~7vEK%CM3bh zO?i3s8ofq12XVpZ+2`PBH}ICHeH_d6y~sX-)oBhTTG!G))4bjZ9=?QA;(!wdhM8Gf z8i^9&w9ls$qo^xVQe$Jk8&BLGzOvHQWZ=`)$ijHQ$73&#BbM39g_S`I8}0n&klv47 zvl?oTfL1&0BM&Vwn&vid1O=wH@Fte?1>ih^%xBY~L?LnXksEz=I4$klez$jjO#>qf z#Lww-`+`3Nutyxzx`9^-WMNNAV5?U&HMbg;svK^+9z(&}fM_+RuF`R(J>W7WtGpbs zQ};1AO)x#fg(nDwv<8jd?_b4us&>ELH;2blLf@YD-1@qaNvP#ZS zm+Z)3Ae_M|f!#T}nINr&KvS#CN2wq4oFaRU(yQU+wqMRZ%e3^u<@wNiJP)0?d3Ie! zw8m-mz71iJbU{+(s0EKlc9WmoSZUaAwL zla)R}^V`h@QDLzU9D}8&7K58M$A|@^1W=}`uH98xU(TRa1gdS8Lse8!g{Y8)(_Pl=5&Qnv@XD{ z*mWe!Hsk8QE%&A|6KX15P@XqIsR>QUa#~uM`mk=Xgn@xAgkIN~rZGz(?E706=PK3% zTGqL`(HhsMOHNNw3EJM1EeKqK2Od}i*VFHnZfTFDqh~>NS5q@s_W|3XIZcr!8l=mCVw$k%f=8KC2I`!=twb{LVOP14Gym+iT*QMkQfU;ci`k3 zpIR4`L+MFPO<09HYOqv8_3mF}4SBbgcXvB4KUInPOyY$X!)OJg`ZrG3TAR*1ZZ3=- zyD66>g7sQmBnNgNYP#zP7F=_D96vjgKR+lo*&_A+;f42uueQk^SGDAgO@17FTkoXU zt=w=^TZ?wRZ>RTEKL4YR6Ou(_zS&FRS8PhvAIO#JF5Bwd}>YLb` z(77+hk@P1`u>wvBb9&!E@cYosnekXk1ZXKr6&$lc!yhZ_r@krcS=j6m-UXgjYZ$B!j zu<0M5l;Kv~hpJtgKY$MpI35wZScfEW5T8k*fD0;x^zAzi(v-Ydi~OKx!FSQLL>33^ zskLoklqm8Rse9aj=jG+~VwtOWP_8yV24N=sIJG6rm--!?^x)KGMtT(@j>Rsu*YuxA zO59)I*?b(Wu*%9mGx6hF`v02f+P6OM_s?%UBAx%_{f3&#b#XVcR`0oZFKzZ$qZu@ zZaGe!I8Emy)2jTvQ{NvxF>y8bY*3}+0iG}lnWqb!++uKe3OQin6l9`es`>+VJUX< z4B-HR8jh3>1_lKNPZ!6KiaBp?IPx+m2pljtu>ZL;3;(7ip&Pz`J9CB!sDs0LKQoYG zh?A57k`D6@G6Jb5qnyz&7)=MGd116X7%dY=>xI$kaI{G<+AJDv8jd!PN4p54J)_Z{ z(P+Luk*WYrKv;mpbO`ti5 z8^WLh^}xIbK$77b3pRE!@&P#s{slmCRLf|HjV74U{4!cxJOGu3 zqopM<5JoEtU?5J~G2y85}Sb4q9e0GZZ8JOBUy From 78a4e756367292ac3d13001a1f555c94f834bfdf Mon Sep 17 00:00:00 2001 From: Georgy Steshin Date: Tue, 3 Dec 2024 12:04:49 +0200 Subject: [PATCH 15/24] Added view-hierarchy-test snapshots --- .../view-hierarchy-web-view.75.android.txt | 57 +++++++++++++++++++ ...rchy-with-test-id-injection.75.android.txt | 29 ++++++++++ ...y-without-test-id-injection.75.android.txt | 29 ++++++++++ 3 files changed, 115 insertions(+) create mode 100644 detox/test/e2e/assets/view-hierarchy-web-view.75.android.txt create mode 100644 detox/test/e2e/assets/view-hierarchy-with-test-id-injection.75.android.txt create mode 100644 detox/test/e2e/assets/view-hierarchy-without-test-id-injection.75.android.txt diff --git a/detox/test/e2e/assets/view-hierarchy-web-view.75.android.txt b/detox/test/e2e/assets/view-hierarchy-web-view.75.android.txt new file mode 100644 index 0000000000..c561d7e3fa --- /dev/null +++ b/detox/test/e2e/assets/view-hierarchy-web-view.75.android.txt @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + +

First Webview

+

Form

+
+
+
+ +
+ +

Form Results

+

Your first name is: No input yet

+ +

Content Editable

+
Name:
+ +

Text and link

+

Some text and a link.

+

This is a bottom paragraph with class.

+ + +"]]> +
+
+
+ + + +
+
+
+
+
+ + +
+
\ No newline at end of file diff --git a/detox/test/e2e/assets/view-hierarchy-with-test-id-injection.75.android.txt b/detox/test/e2e/assets/view-hierarchy-with-test-id-injection.75.android.txt new file mode 100644 index 0000000000..9437066dc2 --- /dev/null +++ b/detox/test/e2e/assets/view-hierarchy-with-test-id-injection.75.android.txt @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/detox/test/e2e/assets/view-hierarchy-without-test-id-injection.75.android.txt b/detox/test/e2e/assets/view-hierarchy-without-test-id-injection.75.android.txt new file mode 100644 index 0000000000..33e093a0da --- /dev/null +++ b/detox/test/e2e/assets/view-hierarchy-without-test-id-injection.75.android.txt @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From ae589b3a16058f398cdc9db894f38fd01464de4b Mon Sep 17 00:00:00 2001 From: Georgy Steshin Date: Tue, 3 Dec 2024 12:12:26 +0200 Subject: [PATCH 16/24] Added iOS view hierarchy test --- .../assets/view-hierarchy-web-view.73.ios.txt | 23 +++++- .../assets/view-hierarchy-web-view.75.ios.txt | 79 +++++++++++++++++++ ...ierarchy-with-test-id-injection.75.ios.txt | 38 +++++++++ ...archy-without-test-id-injection.75.ios.txt | 38 +++++++++ 4 files changed, 174 insertions(+), 4 deletions(-) create mode 100644 detox/test/e2e/assets/view-hierarchy-web-view.75.ios.txt create mode 100644 detox/test/e2e/assets/view-hierarchy-with-test-id-injection.75.ios.txt create mode 100644 detox/test/e2e/assets/view-hierarchy-without-test-id-injection.75.ios.txt diff --git a/detox/test/e2e/assets/view-hierarchy-web-view.73.ios.txt b/detox/test/e2e/assets/view-hierarchy-web-view.73.ios.txt index cdf809ae6d..589c65cd6e 100644 --- a/detox/test/e2e/assets/view-hierarchy-web-view.73.ios.txt +++ b/detox/test/e2e/assets/view-hierarchy-web-view.73.ios.txt @@ -27,8 +27,8 @@ - - + +

First Webview

@@ -38,22 +38,29 @@
+

Form Results

Your first name is: No input yet

+

Content Editable

Name:
+

Text and link

Some text and a link.

This is a bottom paragraph with class.

+ ]]> -
-
+ +
+ + + @@ -61,4 +68,12 @@ + + + + + + + + diff --git a/detox/test/e2e/assets/view-hierarchy-web-view.75.ios.txt b/detox/test/e2e/assets/view-hierarchy-web-view.75.ios.txt new file mode 100644 index 0000000000..bd09affcbf --- /dev/null +++ b/detox/test/e2e/assets/view-hierarchy-web-view.75.ios.txt @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

First Webview

+

Form

+
+
+
+ +
+ +

Form Results

+

Your first name is: No input yet

+ +

Content Editable

+
Name:
+ +

Text and link

+

Some text and a link.

+

This is a bottom paragraph with class.

+ + +]]> +
+
+
+
+
+
+
+ + + +
+
+
+
+
+ +
+ + + + + + + + +
\ No newline at end of file diff --git a/detox/test/e2e/assets/view-hierarchy-with-test-id-injection.75.ios.txt b/detox/test/e2e/assets/view-hierarchy-with-test-id-injection.75.ios.txt new file mode 100644 index 0000000000..4d4dcbcd9c --- /dev/null +++ b/detox/test/e2e/assets/view-hierarchy-with-test-id-injection.75.ios.txt @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/detox/test/e2e/assets/view-hierarchy-without-test-id-injection.75.ios.txt b/detox/test/e2e/assets/view-hierarchy-without-test-id-injection.75.ios.txt new file mode 100644 index 0000000000..cf16dfd6f8 --- /dev/null +++ b/detox/test/e2e/assets/view-hierarchy-without-test-id-injection.75.ios.txt @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 8632e10fc8d9e7bb14175dd5b87bf813f6d052c7 Mon Sep 17 00:00:00 2001 From: Georgy Steshin Date: Tue, 3 Dec 2024 15:05:22 +0200 Subject: [PATCH 17/24] Fixed snapshots --- .../view-hierarchy-web-view.73.android.txt | 102 +++++++++--------- .../assets/view-hierarchy-web-view.73.ios.txt | 15 +-- 2 files changed, 56 insertions(+), 61 deletions(-) diff --git a/detox/test/e2e/assets/view-hierarchy-web-view.73.android.txt b/detox/test/e2e/assets/view-hierarchy-web-view.73.android.txt index 1043026a47..2ed43252ac 100644 --- a/detox/test/e2e/assets/view-hierarchy-web-view.73.android.txt +++ b/detox/test/e2e/assets/view-hierarchy-web-view.73.android.txt @@ -1,48 +1,54 @@ - - - - - - - - - - - - - - - - - - - - - -

First Webview

-

Form

-
-
-
- -
-

Form Results

-

Your first name is: No input yet

-

Content Editable

-
Name:
-

Text and link

-

Some text and a link.

-

This is a bottom paragraph with class.

- -"]]> -
-
-
-
-
-
-
- - -
-
+ + + + + + + + + + + + + + + + + + + + + + +

First Webview

+

Form

+
+
+
+ +
+ +

Form Results

+

Your first name is: No input yet

+ +

Content Editable

+
Name:
+ +

Text and link

+

Some text and a link.

+

This is a bottom paragraph with class.

+ + +"]]> +
+
+
+
+
+
+
+
+ + +
+
\ No newline at end of file diff --git a/detox/test/e2e/assets/view-hierarchy-web-view.73.ios.txt b/detox/test/e2e/assets/view-hierarchy-web-view.73.ios.txt index 589c65cd6e..22552e8c06 100644 --- a/detox/test/e2e/assets/view-hierarchy-web-view.73.ios.txt +++ b/detox/test/e2e/assets/view-hierarchy-web-view.73.ios.txt @@ -48,7 +48,7 @@

Text and link

Some text and a link.

This is a bottom paragraph with class.

- + ]]> @@ -58,9 +58,6 @@ - - - @@ -68,12 +65,4 @@ - - - - - - - - - + \ No newline at end of file From cef3b6211b8b61c2344dd67b1eea90870b37cb20 Mon Sep 17 00:00:00 2001 From: Georgy Steshin Date: Tue, 3 Dec 2024 16:07:13 +0200 Subject: [PATCH 18/24] Fixed snapshots --- .../test/e2e/06.device.view-hierarchy.test.js | 1 - .../view-hierarchy-web-view.75.android.txt | 3 -- .../assets/view-hierarchy-web-view.75.ios.txt | 47 +++++++------------ ...rchy-with-test-id-injection.75.android.txt | 3 -- ...ierarchy-with-test-id-injection.75.ios.txt | 25 +++------- ...y-without-test-id-injection.75.android.txt | 3 -- ...archy-without-test-id-injection.75.ios.txt | 25 +++------- 7 files changed, 29 insertions(+), 78 deletions(-) diff --git a/detox/test/e2e/06.device.view-hierarchy.test.js b/detox/test/e2e/06.device.view-hierarchy.test.js index 0e52629021..7b72381676 100644 --- a/detox/test/e2e/06.device.view-hierarchy.test.js +++ b/detox/test/e2e/06.device.view-hierarchy.test.js @@ -26,7 +26,6 @@ describe('generate view hierarchy', () => { it('generateViewHierarchyXml() - should generate xml for web view', async () => { await element(by.text('WebView')).tap(); const hierarchy = await device.generateViewHierarchyXml(); - console.log(hierarchy); await expectViewHierarchySnapshotToMatch(hierarchy, `view-hierarchy-web-view`); }); diff --git a/detox/test/e2e/assets/view-hierarchy-web-view.75.android.txt b/detox/test/e2e/assets/view-hierarchy-web-view.75.android.txt index c561d7e3fa..2ed43252ac 100644 --- a/detox/test/e2e/assets/view-hierarchy-web-view.75.android.txt +++ b/detox/test/e2e/assets/view-hierarchy-web-view.75.android.txt @@ -43,9 +43,6 @@ - - - diff --git a/detox/test/e2e/assets/view-hierarchy-web-view.75.ios.txt b/detox/test/e2e/assets/view-hierarchy-web-view.75.ios.txt index bd09affcbf..8e020b72e1 100644 --- a/detox/test/e2e/assets/view-hierarchy-web-view.75.ios.txt +++ b/detox/test/e2e/assets/view-hierarchy-web-view.75.ios.txt @@ -7,29 +7,28 @@ - - - - - - - + + + + + - - - - - + + + + + + + - - - - + + +

First Webview

Form

@@ -51,16 +50,12 @@ ]]> -
-
-
+ +
- - -
@@ -68,12 +63,4 @@ - - - - - - - - \ No newline at end of file diff --git a/detox/test/e2e/assets/view-hierarchy-with-test-id-injection.75.android.txt b/detox/test/e2e/assets/view-hierarchy-with-test-id-injection.75.android.txt index 9437066dc2..e26d5f661c 100644 --- a/detox/test/e2e/assets/view-hierarchy-with-test-id-injection.75.android.txt +++ b/detox/test/e2e/assets/view-hierarchy-with-test-id-injection.75.android.txt @@ -15,9 +15,6 @@ - - - diff --git a/detox/test/e2e/assets/view-hierarchy-with-test-id-injection.75.ios.txt b/detox/test/e2e/assets/view-hierarchy-with-test-id-injection.75.ios.txt index 4d4dcbcd9c..fba29973c5 100644 --- a/detox/test/e2e/assets/view-hierarchy-with-test-id-injection.75.ios.txt +++ b/detox/test/e2e/assets/view-hierarchy-with-test-id-injection.75.ios.txt @@ -7,18 +7,13 @@ - - - - - - - - + + + + + + - - - @@ -27,12 +22,4 @@ - - - - - - - - \ No newline at end of file diff --git a/detox/test/e2e/assets/view-hierarchy-without-test-id-injection.75.android.txt b/detox/test/e2e/assets/view-hierarchy-without-test-id-injection.75.android.txt index 33e093a0da..3bef9cb10f 100644 --- a/detox/test/e2e/assets/view-hierarchy-without-test-id-injection.75.android.txt +++ b/detox/test/e2e/assets/view-hierarchy-without-test-id-injection.75.android.txt @@ -15,9 +15,6 @@ - - - diff --git a/detox/test/e2e/assets/view-hierarchy-without-test-id-injection.75.ios.txt b/detox/test/e2e/assets/view-hierarchy-without-test-id-injection.75.ios.txt index cf16dfd6f8..fd1fc31bac 100644 --- a/detox/test/e2e/assets/view-hierarchy-without-test-id-injection.75.ios.txt +++ b/detox/test/e2e/assets/view-hierarchy-without-test-id-injection.75.ios.txt @@ -7,18 +7,13 @@ - - - - - - - - + + + + + + - - - @@ -27,12 +22,4 @@ - - - - - - - - \ No newline at end of file From 935ff4c33e9675c013eff75100db96140a486ad5 Mon Sep 17 00:00:00 2001 From: Georgy Steshin Date: Tue, 3 Dec 2024 16:10:51 +0200 Subject: [PATCH 19/24] Upgraded docs --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7bcd9eeb76..8a8a67876e 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ The most difficult part of automated testing on mobile is the tip of the testing Detox was built from the ground up to support React Native projects. -While Detox should work out of the box with almost any React Native version of the latest minor releases, official support is provided for React Native versions `0.71.x`, `0.72.x`, `0.73.x`, `0.74.x` without React Native's ["New Architecture"](https://reactnative.dev/docs/the-new-architecture/landing-page). +While Detox should work out of the box with almost any React Native version of the latest minor releases, official support is provided for React Native versions `0.72.x`, `0.73.x`, `0.74.x`, `0.75.x` without React Native's ["New Architecture"](https://reactnative.dev/docs/the-new-architecture/landing-page). Newer versions, as well as React Native's "New Architecture", may work with Detox, but have not been tested out yet by the Detox team. From 4a7d6941a6f1852a3434e9020831836ec9d7669f Mon Sep 17 00:00:00 2001 From: Georgy Steshin Date: Wed, 4 Dec 2024 14:06:53 +0200 Subject: [PATCH 20/24] Update README.md Co-authored-by: d4vidi --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8a8a67876e..286ba0d935 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ The most difficult part of automated testing on mobile is the tip of the testing Detox was built from the ground up to support React Native projects. -While Detox should work out of the box with almost any React Native version of the latest minor releases, official support is provided for React Native versions `0.72.x`, `0.73.x`, `0.74.x`, `0.75.x` without React Native's ["New Architecture"](https://reactnative.dev/docs/the-new-architecture/landing-page). +While Detox should work out of the box with almost any React Native version of the latest minor releases, official support is provided for React Native versions `0.72.x`, `0.73.x`, `0.74.x`, `0.75.x` with or without React Native's ["New Architecture"](https://reactnative.dev/docs/the-new-architecture/landing-page). Newer versions, as well as React Native's "New Architecture", may work with Detox, but have not been tested out yet by the Detox team. From 140ba1bd9487d2a9ccbcf470a4426f2a9a9be496 Mon Sep 17 00:00:00 2001 From: Georgy Steshin Date: Wed, 4 Dec 2024 14:07:21 +0200 Subject: [PATCH 21/24] Update detox/test/android/app/src/main/java/com/example/MainActivity.kt Co-authored-by: d4vidi --- .../android/app/src/main/java/com/example/MainActivity.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/detox/test/android/app/src/main/java/com/example/MainActivity.kt b/detox/test/android/app/src/main/java/com/example/MainActivity.kt index 9ee730d64a..ca01208db4 100644 --- a/detox/test/android/app/src/main/java/com/example/MainActivity.kt +++ b/detox/test/android/app/src/main/java/com/example/MainActivity.kt @@ -16,9 +16,7 @@ open class MainActivity : ReactActivity() { * Returns the name of the main component registered from JavaScript. * This is used to schedule rendering of the component. */ - override fun getMainComponentName(): String { - return "example" - } + override fun getMainComponentName() = "example" /** * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate] From 0fde209c9becacf00506c23c166e7265393fb31b Mon Sep 17 00:00:00 2001 From: Georgy Steshin Date: Wed, 4 Dec 2024 14:08:50 +0200 Subject: [PATCH 22/24] Update detox/android/detox/src/full/java/com/wix/detox/espresso/web/WebViewElement.java Co-authored-by: d4vidi --- .../full/java/com/wix/detox/espresso/web/WebViewElement.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detox/android/detox/src/full/java/com/wix/detox/espresso/web/WebViewElement.java b/detox/android/detox/src/full/java/com/wix/detox/espresso/web/WebViewElement.java index 641a5011fe..7be8950046 100644 --- a/detox/android/detox/src/full/java/com/wix/detox/espresso/web/WebViewElement.java +++ b/detox/android/detox/src/full/java/com/wix/detox/espresso/web/WebViewElement.java @@ -30,7 +30,7 @@ public class WebViewElement { @Override protected boolean matchesSafely(View item) { // Support for react-native-webview >= 13.0.0 - if (item instanceof WebView && item.getParent().getClass().getSimpleName().equals("RNCWebViewWrapper")) { + if (item instanceof WebView && item.getParent().getClass().getSimpleName().equals(WRAPPER_WEBVIEW_CLASS_NAME)) { return userMatcher.matches(item.getParent()); } From 7796ab4c78ff5e0bad479cd245954aaa61c6f0b1 Mon Sep 17 00:00:00 2001 From: Georgy Steshin Date: Wed, 4 Dec 2024 14:30:59 +0200 Subject: [PATCH 23/24] Fixes after PR --- .buildkite/jobs/pipeline.android_rn_74.yml | 12 ------------ .buildkite/jobs/pipeline.ios_demo_app_rn_74.yml | 9 --------- .buildkite/jobs/pipeline.ios_rn_74.yml | 10 ---------- .buildkite/pipeline_common.sh | 3 --- detox/android/settings.gradle | 3 +++ detox/scripts/updateGradle.js | 7 ++++--- detox/test/android/settings.gradle | 2 ++ 7 files changed, 9 insertions(+), 37 deletions(-) delete mode 100644 .buildkite/jobs/pipeline.android_rn_74.yml delete mode 100644 .buildkite/jobs/pipeline.ios_demo_app_rn_74.yml delete mode 100644 .buildkite/jobs/pipeline.ios_rn_74.yml diff --git a/.buildkite/jobs/pipeline.android_rn_74.yml b/.buildkite/jobs/pipeline.android_rn_74.yml deleted file mode 100644 index 030ca787fe..0000000000 --- a/.buildkite/jobs/pipeline.android_rn_74.yml +++ /dev/null @@ -1,12 +0,0 @@ - - label: ":android::detox: RN .74 + Android: Tests app" - command: - - "nvm install" - - "./scripts/ci.android.sh" - env: - REACT_NATIVE_VERSION: 0.74.6 - DETOX_DISABLE_POD_INSTALL: true - DETOX_DISABLE_POSTINSTALL: true - artifact_paths: - - "/Users/builder/uibuilder/work/coverage/**/*.lcov" - - "/Users/builder/uibuilder/work/**/allure-report-*.html" - - "/Users/builder/uibuilder/work/artifacts*.tar.gz" diff --git a/.buildkite/jobs/pipeline.ios_demo_app_rn_74.yml b/.buildkite/jobs/pipeline.ios_demo_app_rn_74.yml deleted file mode 100644 index 2ebc9493f4..0000000000 --- a/.buildkite/jobs/pipeline.ios_demo_app_rn_74.yml +++ /dev/null @@ -1,9 +0,0 @@ - - label: ":ios::react: RN .74 + iOS: Demo app" - command: - - "nvm install" - - "./scripts/demo-projects.ios.sh" - env: - REACT_NATIVE_VERSION: 0.74.6 - artifact_paths: - - "/Users/builder/uibuilder/work/coverage/**/*.lcov" - - "/Users/builder/uibuilder/work/artifacts*.tar.gz" diff --git a/.buildkite/jobs/pipeline.ios_rn_74.yml b/.buildkite/jobs/pipeline.ios_rn_74.yml deleted file mode 100644 index 048e1ae9c8..0000000000 --- a/.buildkite/jobs/pipeline.ios_rn_74.yml +++ /dev/null @@ -1,10 +0,0 @@ - - label: ":ios::detox: RN .74 + iOS: Tests app" - command: - - "nvm install" - - "./scripts/ci.ios.sh" - env: - REACT_NATIVE_VERSION: 0.74.6 - artifact_paths: - - "/Users/builder/uibuilder/work/coverage/**/*.lcov" - - "/Users/builder/uibuilder/work/**/allure-report-*.html" - - "/Users/builder/uibuilder/work/artifacts*.tar.gz" diff --git a/.buildkite/pipeline_common.sh b/.buildkite/pipeline_common.sh index 0ce726fa02..cae5e1e799 100755 --- a/.buildkite/pipeline_common.sh +++ b/.buildkite/pipeline_common.sh @@ -3,13 +3,10 @@ echo "steps:" cat .buildkite/jobs/pipeline.ios_rn_75.yml -cat .buildkite/jobs/pipeline.ios_rn_74.yml cat .buildkite/jobs/pipeline.ios_rn_73.yml cat .buildkite/jobs/pipeline.ios_demo_app_rn_75.yml -cat .buildkite/jobs/pipeline.ios_demo_app_rn_74.yml cat .buildkite/jobs/pipeline.ios_demo_app_rn_73.yml cat .buildkite/jobs/pipeline.android_rn_75.yml -cat .buildkite/jobs/pipeline.android_rn_74.yml cat .buildkite/jobs/pipeline.android_rn_73.yml cat .buildkite/jobs/pipeline.android_demo_app_rn_75.yml cat .buildkite/pipeline.post_processing.yml diff --git a/detox/android/settings.gradle b/detox/android/settings.gradle index c65d71c825..4f3e8d3746 100644 --- a/detox/android/settings.gradle +++ b/detox/android/settings.gradle @@ -1,6 +1,9 @@ +// RN75+_BLOCK_START pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") } plugins { id("com.facebook.react.settings") } extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() } +// RN75+_BLOCK_END + apply from: '../android/rninfo.gradle' include ':detox' diff --git a/detox/scripts/updateGradle.js b/detox/scripts/updateGradle.js index ac401c2721..e3e45b19bd 100644 --- a/detox/scripts/updateGradle.js +++ b/detox/scripts/updateGradle.js @@ -41,9 +41,10 @@ function patchSettingsGradle() { try { let data = fs.readFileSync(settingsGradlePath, 'utf8'); - let updatedData = data.replace('pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") }', ''); - updatedData = updatedData.replace('plugins { id("com.facebook.react.settings") }', ''); - updatedData = updatedData.replace('extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() }', ''); + const blockRegex = /\/\/ RN75\+_BLOCK_START[\s\S]*?\/\/ RN75\+_BLOCK_END/g; + + // Replace the block with an empty string + const updatedData = data.replace(blockRegex, ''); fs.writeFileSync(settingsGradlePath, updatedData, 'utf8'); console.log('settings.gradle patched successfully.'); diff --git a/detox/test/android/settings.gradle b/detox/test/android/settings.gradle index a67506e750..88bb8d0eb1 100644 --- a/detox/test/android/settings.gradle +++ b/detox/test/android/settings.gradle @@ -1,6 +1,8 @@ +// RN75+_BLOCK_START pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") } plugins { id("com.facebook.react.settings") } extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() } +// RN75+_BLOCK_END apply from: file("../../android/rninfo.gradle") println "[settings] RNInfo: detected React Native version: (major=${ext.rnInfo.version})" From c93ecf60f204bcd1954014386ae31b9511894a32 Mon Sep 17 00:00:00 2001 From: Georgy Steshin Date: Wed, 4 Dec 2024 14:32:13 +0200 Subject: [PATCH 24/24] Fixes after PR --- .../full/java/com/wix/detox/espresso/web/WebViewElement.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/detox/android/detox/src/full/java/com/wix/detox/espresso/web/WebViewElement.java b/detox/android/detox/src/full/java/com/wix/detox/espresso/web/WebViewElement.java index 7be8950046..0b84ce8c3a 100644 --- a/detox/android/detox/src/full/java/com/wix/detox/espresso/web/WebViewElement.java +++ b/detox/android/detox/src/full/java/com/wix/detox/espresso/web/WebViewElement.java @@ -19,6 +19,8 @@ public class WebViewElement { + private final static String WRAPPER_WEBVIEW_CLASS_NAME = "RNCWebViewWrapper"; + final Web.WebInteraction webViewInteraction; WebViewElement(@Nullable Matcher userMatcher) {