From 9929a99c840ddc3d9458a665394ec605a2a79a7e Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Wed, 22 Jan 2025 12:57:01 +0100 Subject: [PATCH 01/60] update sign up flow for updated design --- e2e/flows/onboarding/signup.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/e2e/flows/onboarding/signup.yml b/e2e/flows/onboarding/signup.yml index b9955ac828d..b7e1db3d6d2 100644 --- a/e2e/flows/onboarding/signup.yml +++ b/e2e/flows/onboarding/signup.yml @@ -3,23 +3,24 @@ appId: ${MAESTRO_APP_ID} - launchApp: clearState: true clearKeychain: true -- tapOn: "Sign up.*" -- tapOn: "Continue with Email.*" - runScript: file: signup.js +- assertVisible: "Sign up or log in" +- tapOn: "Email Input" - inputText: ${output.signup.email} -- tapOn: "Next.*" +- tapOn: "Continue.*" - inputText: ${output.signup.password} -- tapOn: "Next.*" +- tapOn: "Continue.*" - inputText: "Test McTest" - runFlow: when: platform: iOS commands: - - tapOn: "checkbox of consent By checking this box, you consent to our Terms of Use, Privacy Policy, and Conditions of Sale." + - tapOn: + point: 15%,36% - runFlow: when: platform: Android commands: - tapOn: "Accept terms and privacy policy, Check this element to accept Artsy's terms and privacy policy" -- tapOn: "Next.*" +- tapOn: "Continue.*" From c92bc80076a71059b2c1498f23a7644b7c8e2a50 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Wed, 22 Jan 2025 12:58:04 +0100 Subject: [PATCH 02/60] accesibility labels for easier testing --- src/app/Scenes/Onboarding/Auth2/scenes/LoginPasswordStep.tsx | 1 + src/app/Scenes/Onboarding/Auth2/scenes/LoginWelcomeStep.tsx | 1 + 2 files changed, 2 insertions(+) diff --git a/src/app/Scenes/Onboarding/Auth2/scenes/LoginPasswordStep.tsx b/src/app/Scenes/Onboarding/Auth2/scenes/LoginPasswordStep.tsx index 7e3cc7d6ce5..67e3697eef6 100644 --- a/src/app/Scenes/Onboarding/Auth2/scenes/LoginPasswordStep.tsx +++ b/src/app/Scenes/Onboarding/Auth2/scenes/LoginPasswordStep.tsx @@ -120,6 +120,7 @@ const LoginPasswordStepForm: React.FC = () => { { Date: Wed, 22 Jan 2025 15:16:10 +0100 Subject: [PATCH 03/60] assert on welcome screen to make wait reliably --- e2e/flows/onboarding/signupWithoutOnboarding.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/e2e/flows/onboarding/signupWithoutOnboarding.yml b/e2e/flows/onboarding/signupWithoutOnboarding.yml index dd4f22bdf48..9ce5e6beb0e 100644 --- a/e2e/flows/onboarding/signupWithoutOnboarding.yml +++ b/e2e/flows/onboarding/signupWithoutOnboarding.yml @@ -2,5 +2,6 @@ appId: ${MAESTRO_APP_ID} --- - runFlow: file: signup.yml +- assertVisible: "Ready to find art you love?" - tapOn: "Skip.*" - assertVisible: "New Works for You" From b1eb0f4b6058bb71451187a9164fa4573d510443 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Wed, 22 Jan 2025 15:22:45 +0100 Subject: [PATCH 04/60] update login flow --- e2e/flows/onboarding/login.yml | 27 ++++----------------------- e2e/set_env_vars.sh | 6 ++++++ ios/Podfile.lock | 2 +- 3 files changed, 11 insertions(+), 24 deletions(-) create mode 100755 e2e/set_env_vars.sh diff --git a/e2e/flows/onboarding/login.yml b/e2e/flows/onboarding/login.yml index 7dc9535ca5d..bec7be23ec7 100644 --- a/e2e/flows/onboarding/login.yml +++ b/e2e/flows/onboarding/login.yml @@ -3,29 +3,10 @@ appId: ${MAESTRO_APP_ID} - launchApp: clearState: true clearKeychain: true -- tapOn: "Log in.*" -- tapOn: "Continue with Email.*" +- assertVisible: "Sign up or log in" +- tapOn: "Email Input" - inputText: ${MAESTRO_TEST_EMAIL} -- runFlow: - when: - platform: iOS - commands: - - tapOn: "Password show password button" -- runFlow: - when: - platform: Android - commands: - - tapOn: "password" +- tapOn: "Continue.*" - inputText: ${MAESTRO_TEST_PASSWORD} -- tapOn: - id: "loginButton" -# Related to the issue https://github.com/mobile-dev-inc/maestro/issues/1227 -# it avoids getting stuck on iOS modal asking to store the password -- runFlow: - when: - platform: iOS - visible: "Would you like to save this password in your Keychain to use with apps and websites?" - commands: - - tapOn: - id: "Home Grabber" +- tapOn: "Continue.*" - assertVisible: "New Works for You" diff --git a/e2e/set_env_vars.sh b/e2e/set_env_vars.sh new file mode 100755 index 00000000000..69977de4d88 --- /dev/null +++ b/e2e/set_env_vars.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +# TODO: make work for android as well +export MAESTRO_APP_ID=net.artsy.artsy +export MAESTRO_TEST_EMAIL=detox+test@example.com +export MAESTRO_TEST_PASSWORD='$###$someT0ughP4$$' \ No newline at end of file diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 9506df5b9de..e44731500f9 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -2744,7 +2744,7 @@ SPEC CHECKSUMS: PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 Pulley: edc993fb57f7eb20541c8453d0fce10559f21dac Quick: ce1276c7c27ba2da3cb2fd0cde053c3648b3b22d - RCT-Folly: 84578c8756030547307e4572ab1947de1685c599 + RCT-Folly: 34124ae2e667a0e5f0ea378db071d27548124321 RCTDeprecation: fb7d408617e25d7f537940000d766d60149c5fea RCTRequired: 9aaf0ffcc1f41f0c671af863970ef25c422a9920 RCTTypeSafety: e9a6e7d48184646eb0610295b74c0dd02768cbb2 From 4196325dcf20b1e098ffc434990a2500028fd28f Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Wed, 22 Jan 2025 15:27:04 +0100 Subject: [PATCH 05/60] get rid of broken license check for now --- .circleci/config.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 82350230321..14ad94e9150 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -200,9 +200,6 @@ jobs: - run: name: Update rollout if needed command: ./scripts/deploys/update-android-rollout-if-needed - - run: - name: Notify if license agreement needs to be signed - command: ./scripts/deploys/notify-if-new-license-agreement deploy-nightly-beta: environment: From a47bea1336559255f065b2f43bbd927e5fa2a908 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Wed, 22 Jan 2025 15:40:54 +0100 Subject: [PATCH 06/60] attempt to install maestro in ci --- .circleci/config.yml | 160 +++++++++++++++++++++++++++++-------------- 1 file changed, 107 insertions(+), 53 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 14ad94e9150..6754f9c66ae 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -201,6 +201,52 @@ jobs: name: Update rollout if needed command: ./scripts/deploys/update-android-rollout-if-needed + run-e2e-tests: + environment: + BUNDLE_PATH: .vendor # path to install gems and use for caching + + macos: + xcode: 16.1 + resource_class: macos.m1.medium.gen1 + + steps: + - attach_workspace: + at: ../workspace + - run: + name: Install maestro + command: curl -Ls "https://get.maestro.mobile.dev" | bash + - run: + name: Test maestro install + command: maestro --version + # - run: + # name: Clear project dir + # command: | + # rm -rf /Users/distiller/project/* + # - checkout + # - attach_workspace: + # at: . + # - install-node + # - setup-awscli + # - setup-env-file + # - install-node-modules + # - run-relay-compiler + # - update-echo + # - install-gems + # - install-cocoapods + # - macos/preboot-simulator: + # version: "18.1" + # platform: "iOS" + # device: "iPhone 16 Pro" + # - build-app-ios + + # - store_artifacts: + # path: xcode_build_raw.log + # prefix: build + + # - store_artifacts: + # path: xcode_test_raw.log + # prefix: tests + deploy-nightly-beta: environment: BUNDLE_PATH: .vendor @@ -511,6 +557,14 @@ workflows: - deploy-nightly-beta - run-nightly-tasks + run-e2e: + jobs: + - run-e2e-tests: + filters: + branches: + only: + - brian/e2e-again + flag-check: triggers: - schedule: @@ -537,56 +591,56 @@ workflows: ignore: - main - - check-code: - context: danger-github-oss - - - check-and-deploy: - filters: - branches: - only: - - main - - - test-js - - - build-test-js - - - horizon/block: - context: horizon - project_id: 37 - filters: - branches: - only: - - beta-ios - - beta-android - - - build-test-app-ios: - filters: - branches: - ignore: - - beta-android - requires: - - test-js - - check-code - - build-test-js - - horizon/block - - - build-test-app-android: - filters: - branches: - ignore: - - beta-ios - requires: - - test-js - - check-code - - build-test-js - - horizon/block - - - update-metaphysics: - filters: - branches: - only: - - beta-ios - - beta-android - requires: - - build-test-app-ios - - build-test-app-android + # - check-code: + # context: danger-github-oss + + # - check-and-deploy: + # filters: + # branches: + # only: + # - main + + # - test-js + + # - build-test-js + + # - horizon/block: + # context: horizon + # project_id: 37 + # filters: + # branches: + # only: + # - beta-ios + # - beta-android + + # - build-test-app-ios: + # filters: + # branches: + # ignore: + # - beta-android + # requires: + # - test-js + # - check-code + # - build-test-js + # - horizon/block + + # - build-test-app-android: + # filters: + # branches: + # ignore: + # - beta-ios + # requires: + # - test-js + # - check-code + # - build-test-js + # - horizon/block + + # - update-metaphysics: + # filters: + # branches: + # only: + # - beta-ios + # - beta-android + # requires: + # - build-test-app-ios + # - build-test-app-android From 16f3df8e253ce5425e086064834d504ea3b40d71 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Wed, 22 Jan 2025 15:46:02 +0100 Subject: [PATCH 07/60] attempt to run a test in ci --- .circleci/config.yml | 58 +++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6754f9c66ae..94ed755a8c8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -218,34 +218,36 @@ jobs: - run: name: Test maestro install command: maestro --version - # - run: - # name: Clear project dir - # command: | - # rm -rf /Users/distiller/project/* - # - checkout - # - attach_workspace: - # at: . - # - install-node - # - setup-awscli - # - setup-env-file - # - install-node-modules - # - run-relay-compiler - # - update-echo - # - install-gems - # - install-cocoapods - # - macos/preboot-simulator: - # version: "18.1" - # platform: "iOS" - # device: "iPhone 16 Pro" - # - build-app-ios - - # - store_artifacts: - # path: xcode_build_raw.log - # prefix: build - - # - store_artifacts: - # path: xcode_test_raw.log - # prefix: tests + - run: + name: Clear project dir + command: | + rm -rf /Users/distiller/project/* + - checkout + - attach_workspace: + at: . + - install-node + - setup-awscli + - setup-env-file + - install-node-modules + - run-relay-compiler + - update-echo + - install-gems + - install-cocoapods + - macos/preboot-simulator: + version: "18.1" + platform: "iOS" + device: "iPhone 16 Pro" + - build-app-ios + - run: + name: Maestro sign up test + command: maestro test e2e/flows/onboarding/login.yml + - store_artifacts: + path: xcode_build_raw.log + prefix: build + + - store_artifacts: + path: xcode_test_raw.log + prefix: tests deploy-nightly-beta: environment: From 655e178e1c47c9051b70da15629b2fca65661d8b Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Wed, 22 Jan 2025 16:21:24 +0100 Subject: [PATCH 08/60] attempt with s3 download for now --- .circleci/config.yml | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 94ed755a8c8..a3607ee7f72 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -222,32 +222,23 @@ jobs: name: Clear project dir command: | rm -rf /Users/distiller/project/* - - checkout - - attach_workspace: - at: . - - install-node - setup-awscli - - setup-env-file - - install-node-modules - - run-relay-compiler - - update-echo - - install-gems - - install-cocoapods + - run: + name: Download app zip + command: aws s3 cp s3://artsy-citadel/eigen/Artsy.zip ./Artsy.zip + - run: + name: Unzip the app + command: unzip Artsy.zip - macos/preboot-simulator: version: "18.1" platform: "iOS" device: "iPhone 16 Pro" - - build-app-ios + - run: + name: Install app in sim + command: xcrun simctl install booted ./Artsy.app - run: name: Maestro sign up test command: maestro test e2e/flows/onboarding/login.yml - - store_artifacts: - path: xcode_build_raw.log - prefix: build - - - store_artifacts: - path: xcode_test_raw.log - prefix: tests deploy-nightly-beta: environment: From 4edfc549614b14ffa0fd9e6952ba9cd8f8594425 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Wed, 22 Jan 2025 16:24:48 +0100 Subject: [PATCH 09/60] need to check out project --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index a3607ee7f72..162afdc9744 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -222,6 +222,7 @@ jobs: name: Clear project dir command: | rm -rf /Users/distiller/project/* + - checkout - setup-awscli - run: name: Download app zip From d1d1b2b78697ca12405fa72914beea25d17193e3 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Thu, 23 Jan 2025 09:23:23 +0100 Subject: [PATCH 10/60] try using m2 pro --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 162afdc9744..0a38a22b621 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -207,7 +207,7 @@ jobs: macos: xcode: 16.1 - resource_class: macos.m1.medium.gen1 + resource_class: m2pro.medium steps: - attach_workspace: From d6378068aa5d03f612f07949abe0f2a3215a3ab2 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Thu, 23 Jan 2025 16:19:19 +0100 Subject: [PATCH 11/60] ignore maestro folder for now Co-authored-by: George --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 2e15a28e4bc..23c51c8cf3a 100644 --- a/.gitignore +++ b/.gitignore @@ -147,6 +147,9 @@ tsconfig.tsbuildinfo # Temporary files created by Metro to check the health of the file watcher .metro-health-check* +# maestro test artifacts +.maestro/* + ######################################################### # Keep this rule last. # Keep these, so we can keep the folders these appear in. From 1712a5df2d091f653c9a526672b7fac9d276864c Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Thu, 23 Jan 2025 16:19:46 +0100 Subject: [PATCH 12/60] convenience script for installing app in booted sims Co-authored-by: George --- install_app_in_booted_sims.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100755 install_app_in_booted_sims.sh diff --git a/install_app_in_booted_sims.sh b/install_app_in_booted_sims.sh new file mode 100755 index 00000000000..2013749c769 --- /dev/null +++ b/install_app_in_booted_sims.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +# Path to your .app file +APP_PATH="./Artsy.app" + +# Get a list of all booted simulator UUIDs +BOOTED_SIMULATORS=$(xcrun simctl list devices booted | grep -oE "[A-F0-9-]{36}") + +# Install the .app file on each booted simulator +for SIMULATOR in $BOOTED_SIMULATORS; do + echo "Installing $APP_PATH on simulator $SIMULATOR..." + xcrun simctl install $SIMULATOR "$APP_PATH" +done + +echo "Installation completed on all booted simulators!" \ No newline at end of file From 92c37c8674f9999750784917c3e0b58070f2c617 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Thu, 23 Jan 2025 16:21:12 +0100 Subject: [PATCH 13/60] move flows to top level for now Co-authored-by: George --- .../onboarding => broken_flows}/onboardingQuiz.js | 0 .../onboarding => broken_flows}/onboardingQuiz.yml | 0 e2e/config.yml | 11 ++--------- e2e/flows/{onboarding => }/login.yml | 0 e2e/flows/{onboarding => }/signup.js | 0 e2e/flows/{onboarding => }/signup.yml | 0 .../{onboarding => }/signupWithoutOnboarding.yml | 0 7 files changed, 2 insertions(+), 9 deletions(-) rename e2e/{flows/onboarding => broken_flows}/onboardingQuiz.js (100%) rename e2e/{flows/onboarding => broken_flows}/onboardingQuiz.yml (100%) rename e2e/flows/{onboarding => }/login.yml (100%) rename e2e/flows/{onboarding => }/signup.js (100%) rename e2e/flows/{onboarding => }/signup.yml (100%) rename e2e/flows/{onboarding => }/signupWithoutOnboarding.yml (100%) diff --git a/e2e/flows/onboarding/onboardingQuiz.js b/e2e/broken_flows/onboardingQuiz.js similarity index 100% rename from e2e/flows/onboarding/onboardingQuiz.js rename to e2e/broken_flows/onboardingQuiz.js diff --git a/e2e/flows/onboarding/onboardingQuiz.yml b/e2e/broken_flows/onboardingQuiz.yml similarity index 100% rename from e2e/flows/onboarding/onboardingQuiz.yml rename to e2e/broken_flows/onboardingQuiz.yml diff --git a/e2e/config.yml b/e2e/config.yml index 26021c094eb..ee1543c1aad 100644 --- a/e2e/config.yml +++ b/e2e/config.yml @@ -1,9 +1,2 @@ -appId: ${MAESTRO_APP_ID} ---- -- runFlow: - file: flows/onboarding/login.yml -- runFlow: - file: flows/onboarding/signupWithoutOnboarding.yml -# This flow is broken because of performance issues and hangs of the Art Taste Quiz Screen -# - runFlow: -# file: flows/onboarding/onboardingQuiz.yml +flows: + - "flows/*" diff --git a/e2e/flows/onboarding/login.yml b/e2e/flows/login.yml similarity index 100% rename from e2e/flows/onboarding/login.yml rename to e2e/flows/login.yml diff --git a/e2e/flows/onboarding/signup.js b/e2e/flows/signup.js similarity index 100% rename from e2e/flows/onboarding/signup.js rename to e2e/flows/signup.js diff --git a/e2e/flows/onboarding/signup.yml b/e2e/flows/signup.yml similarity index 100% rename from e2e/flows/onboarding/signup.yml rename to e2e/flows/signup.yml diff --git a/e2e/flows/onboarding/signupWithoutOnboarding.yml b/e2e/flows/signupWithoutOnboarding.yml similarity index 100% rename from e2e/flows/onboarding/signupWithoutOnboarding.yml rename to e2e/flows/signupWithoutOnboarding.yml From 312d109697002f397b3e40b7ab5188354636814c Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Thu, 23 Jan 2025 16:27:09 +0100 Subject: [PATCH 14/60] attempt to run tests in parallel in ci Co-authored-by: George --- .circleci/config.yml | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0a38a22b621..7ba4dfa47cb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -212,6 +212,18 @@ jobs: steps: - attach_workspace: at: ../workspace + - macos/preboot-simulator: + version: "18.1" + platform: "iOS" + device: "iPhone 16 Pro Max" + - macos/preboot-simulator: + version: "18.1" + platform: "iOS" + device: "iPhone 16 Pro" + - macos/preboot-simulator: + version: "18.1" + platform: "iOS" + device: "iPhone 16" - run: name: Install maestro command: curl -Ls "https://get.maestro.mobile.dev" | bash @@ -230,16 +242,13 @@ jobs: - run: name: Unzip the app command: unzip Artsy.zip - - macos/preboot-simulator: - version: "18.1" - platform: "iOS" - device: "iPhone 16 Pro" + - run: - name: Install app in sim - command: xcrun simctl install booted ./Artsy.app + name: Install app in booted sims + command: ./install_app_in_booted_sims.sh - run: - name: Maestro sign up test - command: maestro test e2e/flows/onboarding/login.yml + name: Run maestro tests + command: maestro test --shard-split 3 e2e/ deploy-nightly-beta: environment: From 7bca89b609bd48358987d387be7159477b250dcb Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Thu, 23 Jan 2025 17:14:51 +0100 Subject: [PATCH 15/60] increase timeout for maestro tests Co-authored-by: George --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7ba4dfa47cb..9bf72beeec8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -248,6 +248,7 @@ jobs: command: ./install_app_in_booted_sims.sh - run: name: Run maestro tests + no_output_timeout: 25m command: maestro test --shard-split 3 e2e/ deploy-nightly-beta: From 70bee59b66918c434323ae06d53e6438315911c9 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Thu, 23 Jan 2025 17:47:28 +0100 Subject: [PATCH 16/60] basic deeplink testing --- e2e/flows/deeplinks.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 e2e/flows/deeplinks.yml diff --git a/e2e/flows/deeplinks.yml b/e2e/flows/deeplinks.yml new file mode 100644 index 00000000000..a5a4e1ec485 --- /dev/null +++ b/e2e/flows/deeplinks.yml @@ -0,0 +1,20 @@ +appId: ${MAESTRO_APP_ID} +--- +- runFlow: + file: login.yml +- assertVisible: "New Works for You" +- killApp +- openLink: + link: https://www.artsy.net/artist/kaws + autoVerify: false +- assertVisible: "Kaws" +- killApp +- openLink: + link: https://click.artsy.net/f/a/epPWiX0dJaHHMiXAnSrzSg~~/AAQRxQA~/RgRj95QSP0SQaHR0cHM6Ly93d3cuYXJ0c3kubmV0L2NvbGxlY3Rpb24vYXVjdGlvbi1oaWdobGlnaHRzP3V0bV9zb3VyY2U9YnJhemUmdXRtX21lZGl1bT1lbWFpbCZ1dG1fY2FtcGFpZ249bnRmJnV0bV90ZXJtPTYyMTRmYjlkZWI0ZWZkN2RiNjBjZTcwNDk1NWU4NDQ1VwNzcGNCCmIFEg8VYlEJKGBSEmJyaWJlY2sxQGdtYWlsLmNvbVgEAAAAfw~~ + autoVerify: false +- assertVisible: "Highlights at Auction This Week" +- killApp +- openLink: + link: "https://email-link.artsy.net/ls/click?upn=u001.XPbk8dXjc6dwd18Yq2uPM3eTWB4YbDUmeJTAXXTF513sTSKEFRIPxrFgGj8gd2LN9AcRIza5p2-2Fi0huqjv6GWgdnpwA-2FRyTEIYA-2BT1-2F0josxHnYTzJpKeJEmkfzDQlMEY9y6FknqDddY-2BKmm5qtTrTIF2hxySbdUboaYf5ofK-2Bj-2FgSolzBiLvvzai-2FmvjWbSpNpJHWATexQixwLakesmmZUBoRoLkCnxs59pBxJPbB3JZyP13cv77lbfn1WzJ86fiW-2B5MQcd2qss7wLGBI-2BZuy-2FxDkbFuDzpfYPDlaUs1-2BuyO9rqleUCwXPEuyWXZ3aGJrh-_dWIRBTTKlL2IhQqV5a1Cy38Sd4xylePmkTfQkXpdWOLZbG0vcWuzG-2BSSjZ7xaSUgPR0lxFBD0Zz4mpyMqiSRd7GblcbPN8eH0NYfUK6pmADWc2UoFXyJdeq-2F-2BOyOeWlS7O-2FOrHgB9-2BOGtV1nkIFPq97vJTNmWtBMDOt77SsursARR1LHG7CnzBEedV5yll40aEh9LTjA47-2BfpvonTwdxvYfd6ZWsZN2uRczvCs34ipSKUClLSzq0xCn8IjAixssMm2IreBk6LmNzHPC1YLqmZ77pv0qTxX095mxh8mk7f9rJJ8Tg1fyfRFriXGsQqgHlY-2BqTf2aAU6LS9NVXirqdp20-2BHXhzUZbaCnkQNASABts91iKoZaDeV4xnYuuo3L-2F8" + autoVerify: false +- assertVisible: "Jaune 2_40, 2023" From 9f03980a661c449fce34c2e1ab6031f3926e25ac Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Thu, 23 Jan 2025 19:28:27 +0100 Subject: [PATCH 17/60] try using xcode 16.2 --- .circleci/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9bf72beeec8..c3881697349 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -206,22 +206,22 @@ jobs: BUNDLE_PATH: .vendor # path to install gems and use for caching macos: - xcode: 16.1 + xcode: 16.2 resource_class: m2pro.medium steps: - attach_workspace: at: ../workspace - macos/preboot-simulator: - version: "18.1" + version: "18.2" platform: "iOS" device: "iPhone 16 Pro Max" - macos/preboot-simulator: - version: "18.1" + version: "18.2" platform: "iOS" device: "iPhone 16 Pro" - macos/preboot-simulator: - version: "18.1" + version: "18.2" platform: "iOS" device: "iPhone 16" - run: From 8c8af6e801276fd5382537c1fbcc0d7496225f87 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Fri, 24 Jan 2025 07:49:41 +0100 Subject: [PATCH 18/60] add missing idb install --- .circleci/config.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index c3881697349..afbd573fa33 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -227,6 +227,9 @@ jobs: - run: name: Install maestro command: curl -Ls "https://get.maestro.mobile.dev" | bash + - run: + name: Install idb + command: brew tap facebook/fb && brew install idb-companion - run: name: Test maestro install command: maestro --version From b95839276e6bc2235ba525e437bf2b8c4bd5666d Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Fri, 24 Jan 2025 09:06:33 +0100 Subject: [PATCH 19/60] don't clear state for deeplink tests to make more reliable --- e2e/flows/deeplinks.yml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/e2e/flows/deeplinks.yml b/e2e/flows/deeplinks.yml index a5a4e1ec485..cbd4680bc6c 100644 --- a/e2e/flows/deeplinks.yml +++ b/e2e/flows/deeplinks.yml @@ -1,8 +1,19 @@ appId: ${MAESTRO_APP_ID} --- +- launchApp: + clearState: false + clearKeychain: false - runFlow: - file: login.yml -- assertVisible: "New Works for You" + when: + visible: "Sign up or log in" + commands: + - tapOn: "Email Input" + - inputText: ${MAESTRO_TEST_EMAIL} + - tapOn: "Continue.*" + - inputText: ${MAESTRO_TEST_PASSWORD} + - tapOn: "Continue.*" + - assertVisible: "New Works for You" + - assertVisible: "New Works for You" - killApp - openLink: link: https://www.artsy.net/artist/kaws From c003aa8fcfb4c93b59cb242a78dc97f94c773a8f Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Fri, 24 Jan 2025 09:10:36 +0100 Subject: [PATCH 20/60] try just one flow again --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index afbd573fa33..2bfdc137c0a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -252,7 +252,7 @@ jobs: - run: name: Run maestro tests no_output_timeout: 25m - command: maestro test --shard-split 3 e2e/ + command: maestro test e2e/flows/signup.yml deploy-nightly-beta: environment: From 2a9d3ed9a2ce452b46c40dff7bcd72430cfc9ee0 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Fri, 24 Jan 2025 09:26:16 +0100 Subject: [PATCH 21/60] try just booting one simulator --- .circleci/config.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2bfdc137c0a..febdea7e508 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -212,18 +212,18 @@ jobs: steps: - attach_workspace: at: ../workspace - - macos/preboot-simulator: - version: "18.2" - platform: "iOS" - device: "iPhone 16 Pro Max" + # - macos/preboot-simulator: + # version: "18.2" + # platform: "iOS" + # device: "iPhone 16 Pro Max" - macos/preboot-simulator: version: "18.2" platform: "iOS" device: "iPhone 16 Pro" - - macos/preboot-simulator: - version: "18.2" - platform: "iOS" - device: "iPhone 16" + # - macos/preboot-simulator: + # version: "18.2" + # platform: "iOS" + # device: "iPhone 16" - run: name: Install maestro command: curl -Ls "https://get.maestro.mobile.dev" | bash From a700b697a5700bb7ddfd0e33b72ddbbc8b590395 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Fri, 24 Jan 2025 10:58:13 +0100 Subject: [PATCH 22/60] try parallelizing using circle parallelism Co-authored-by: George --- .circleci/config.yml | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index febdea7e508..917d7783d02 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -202,6 +202,8 @@ jobs: command: ./scripts/deploys/update-android-rollout-if-needed run-e2e-tests: + parallelism: 4 + environment: BUNDLE_PATH: .vendor # path to install gems and use for caching @@ -212,18 +214,10 @@ jobs: steps: - attach_workspace: at: ../workspace - # - macos/preboot-simulator: - # version: "18.2" - # platform: "iOS" - # device: "iPhone 16 Pro Max" - macos/preboot-simulator: version: "18.2" platform: "iOS" device: "iPhone 16 Pro" - # - macos/preboot-simulator: - # version: "18.2" - # platform: "iOS" - # device: "iPhone 16" - run: name: Install maestro command: curl -Ls "https://get.maestro.mobile.dev" | bash @@ -245,14 +239,15 @@ jobs: - run: name: Unzip the app command: unzip Artsy.zip - - run: name: Install app in booted sims command: ./install_app_in_booted_sims.sh - run: - name: Run maestro tests + name: Run Maestro Tests no_output_timeout: 25m - command: maestro test e2e/flows/signup.yml + command: | + TEST_FILES=$(find e2e -name "*.yaml" | sort | awk "NR % ${CIRCLE_NODE_TOTAL} == ${CIRCLE_NODE_INDEX}") + echo "$TEST_FILES" | xargs -n 1 maestro test deploy-nightly-beta: environment: From 41df5b6164976e81c3a7c630dd794bdd5e0ef587 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Fri, 24 Jan 2025 11:01:19 +0100 Subject: [PATCH 23/60] duplicate assertion in deeplink test --- e2e/flows/deeplinks.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/e2e/flows/deeplinks.yml b/e2e/flows/deeplinks.yml index cbd4680bc6c..49ef398fbf1 100644 --- a/e2e/flows/deeplinks.yml +++ b/e2e/flows/deeplinks.yml @@ -13,7 +13,6 @@ appId: ${MAESTRO_APP_ID} - inputText: ${MAESTRO_TEST_PASSWORD} - tapOn: "Continue.*" - assertVisible: "New Works for You" - - assertVisible: "New Works for You" - killApp - openLink: link: https://www.artsy.net/artist/kaws From b30764155d44e7faf861dcf25d0158be42d7260a Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Fri, 24 Jan 2025 11:10:04 +0100 Subject: [PATCH 24/60] fix yml matching --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 917d7783d02..185473ce715 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -246,7 +246,7 @@ jobs: name: Run Maestro Tests no_output_timeout: 25m command: | - TEST_FILES=$(find e2e -name "*.yaml" | sort | awk "NR % ${CIRCLE_NODE_TOTAL} == ${CIRCLE_NODE_INDEX}") + TEST_FILES=$(find e2e -name "*.yml" | sort | awk "NR % ${CIRCLE_NODE_TOTAL} == ${CIRCLE_NODE_INDEX}") echo "$TEST_FILES" | xargs -n 1 maestro test deploy-nightly-beta: From 9fe0b4f15bba48d00ebf7e2832f30335e5327c36 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Fri, 24 Jan 2025 11:41:16 +0100 Subject: [PATCH 25/60] add launch args dep and convenience methods for sign in and sign out Co-authored-by: George --- ios/Podfile.lock | 6 ++++++ package.json | 1 + src/app/App.tsx | 18 +++++++++++++++++ yarn.lock | 51 +++++++++--------------------------------------- 4 files changed, 34 insertions(+), 42 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index e44731500f9..7e1a92601be 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1523,6 +1523,8 @@ PODS: - React-Core - react-native-in-app-review (4.3.3): - React-Core + - react-native-launch-arguments (4.0.4): + - React - react-native-netinfo (11.3.2): - React-Core - react-native-pager-view (6.5.0): @@ -2260,6 +2262,7 @@ DEPENDENCIES: - "react-native-geolocation (from `../node_modules/@react-native-community/geolocation`)" - react-native-get-random-values (from `../node_modules/react-native-get-random-values`) - react-native-in-app-review (from `../node_modules/react-native-in-app-review`) + - react-native-launch-arguments (from `../node_modules/react-native-launch-arguments`) - "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)" - react-native-pager-view (from `../node_modules/react-native-pager-view`) - react-native-render-html (from `../node_modules/react-native-render-html`) @@ -2528,6 +2531,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-get-random-values" react-native-in-app-review: :path: "../node_modules/react-native-in-app-review" + react-native-launch-arguments: + :path: "../node_modules/react-native-launch-arguments" react-native-netinfo: :path: "../node_modules/@react-native-community/netinfo" react-native-pager-view: @@ -2783,6 +2788,7 @@ SPEC CHECKSUMS: react-native-geolocation: def10765a5144e7a76837093d43303d70bb6addf react-native-get-random-values: d16467cf726c618e9c7a8c3c39c31faa2244bbba react-native-in-app-review: b3d1eed3d1596ebf6539804778272c4c65e4a400 + react-native-launch-arguments: 8ad8efa525a4c7cb72b3f69f05abfcba86f65dea react-native-netinfo: ce102083db558237dac20cf64172ef569ebe2dd9 react-native-pager-view: a58a82591f421322e2bdb4fb69b82f6486dd4b22 react-native-render-html: 5afc4751f1a98621b3009432ef84c47019dcb2bd diff --git a/package.json b/package.json index c54a8729057..3a8ba1db9e7 100644 --- a/package.json +++ b/package.json @@ -304,6 +304,7 @@ "prop-types": "15.7.2", "pull-lock": "1.0.0", "react-dom": "17.0.2", + "react-native-launch-arguments": "4.0.4", "react-relay-network-modern": "6.2.2", "react-test-renderer": "18.1.0", "reactotron-react-native": "5.1.7", diff --git a/src/app/App.tsx b/src/app/App.tsx index c9ae3e9baa0..d94a43ee22a 100644 --- a/src/app/App.tsx +++ b/src/app/App.tsx @@ -49,6 +49,24 @@ if (__DEV__) { require("../../ReactotronConfig.js") } +if (__DEV__) { + const { LaunchArguments } = require("react-native-launch-arguments") + const args = LaunchArguments.value() + const email = args.email + const password = args.password + const shouldSignOut = args.shouldSignOut + if (email && password) { + GlobalStore.actions.auth.signIn({ + oauthProvider: "email", + oauthMode: "email", + email, + password, + }) + } else if (shouldSignOut) { + GlobalStore.actions.auth.signOut() + } +} + // Sentry must be setup early in the app lifecycle to hook into navigation const debugSentry = unsafe_getDevToggle("DTDebugSentry") const environment = unsafe__getEnvironment() diff --git a/yarn.lock b/yarn.lock index f96d355520e..e5a9b254cb5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1846,7 +1846,7 @@ "@babel/parser" "^7.25.9" "@babel/types" "^7.25.9" -"@babel/traverse--for-generate-function-map@npm:@babel/traverse@^7.25.3": +"@babel/traverse--for-generate-function-map@npm:@babel/traverse@^7.25.3", "@babel/traverse@^7.25.3": version "7.26.4" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.26.4.tgz#ac3a2a84b908dde6d463c3bfa2c5fdc1653574bd" integrity sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w== @@ -1888,19 +1888,6 @@ debug "^4.3.1" globals "^11.1.0" -"@babel/traverse@^7.25.3": - version "7.26.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.26.4.tgz#ac3a2a84b908dde6d463c3bfa2c5fdc1653574bd" - integrity sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w== - dependencies: - "@babel/code-frame" "^7.26.2" - "@babel/generator" "^7.26.3" - "@babel/parser" "^7.26.3" - "@babel/template" "^7.25.9" - "@babel/types" "^7.26.3" - debug "^4.3.1" - globals "^11.1.0" - "@babel/traverse@^7.25.7": version "7.25.7" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.7.tgz#83e367619be1cab8e4f2892ef30ba04c26a40fa8" @@ -13244,6 +13231,11 @@ react-native-keychain@8.0.0: resolved "https://registry.yarnpkg.com/react-native-keychain/-/react-native-keychain-8.0.0.tgz#ff708e4dc2a5440df717179bf9b7cd50f78b61d7" integrity sha512-c7Cs+YQN26UaQsRG1dmlXL7VL2ctnXwH/dl0IOMEQ7ZaL2NdN313YSAI8ZEZZjrVhNmPsyWEuvTFqWrdpItqQg== +react-native-launch-arguments@4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/react-native-launch-arguments/-/react-native-launch-arguments-4.0.4.tgz#5cdf12265b50bf98ad05c87f849da99e07ef5500" + integrity sha512-cB7Sy9m9MX5MvNJliSHEMFWRScSbr95gFuGWnaINBoIK9sP8hloKqhn0vKUHrMQGmNsC1PcpyeiniBqTiU9d5g== + react-native-linear-gradient@2.8.3: version "2.8.3" resolved "https://registry.yarnpkg.com/react-native-linear-gradient/-/react-native-linear-gradient-2.8.3.tgz#9a116649f86d74747304ee13db325e20b21e564f" @@ -14696,16 +14688,7 @@ string-natural-compare@^3.0.1: resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4" integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw== -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -14819,7 +14802,7 @@ stringify-entities@^3.1.0: character-entities-legacy "^1.0.0" xtend "^4.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -14833,13 +14816,6 @@ strip-ansi@^5.0.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" @@ -16263,7 +16239,7 @@ word-wrap@^1.2.3, word-wrap@~1.2.3: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.4.tgz#cb4b50ec9aca570abd1f52f33cd45b6c61739a9f" integrity sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -16281,15 +16257,6 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" From cf2fdb99a725c9851f8aa2a4b2d349d4b84abf6d Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Fri, 24 Jan 2025 11:49:15 +0100 Subject: [PATCH 26/60] use signOut method instead of buggy clearState Co-authored-by: George --- e2e/flows/deeplinks.yml | 1 - e2e/flows/login.yml | 5 +++-- e2e/flows/signup.yml | 5 +++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/e2e/flows/deeplinks.yml b/e2e/flows/deeplinks.yml index 49ef398fbf1..61feee3f7b0 100644 --- a/e2e/flows/deeplinks.yml +++ b/e2e/flows/deeplinks.yml @@ -2,7 +2,6 @@ appId: ${MAESTRO_APP_ID} --- - launchApp: clearState: false - clearKeychain: false - runFlow: when: visible: "Sign up or log in" diff --git a/e2e/flows/login.yml b/e2e/flows/login.yml index bec7be23ec7..764be5370c4 100644 --- a/e2e/flows/login.yml +++ b/e2e/flows/login.yml @@ -1,8 +1,9 @@ appId: ${MAESTRO_APP_ID} --- - launchApp: - clearState: true - clearKeychain: true + clearState: false + arguments: + shouldSignOut: "true" - assertVisible: "Sign up or log in" - tapOn: "Email Input" - inputText: ${MAESTRO_TEST_EMAIL} diff --git a/e2e/flows/signup.yml b/e2e/flows/signup.yml index b7e1db3d6d2..cb0f5025248 100644 --- a/e2e/flows/signup.yml +++ b/e2e/flows/signup.yml @@ -1,8 +1,9 @@ appId: ${MAESTRO_APP_ID} --- - launchApp: - clearState: true - clearKeychain: true + clearState: false + arguments: + shouldSignOut: "true" - runScript: file: signup.js - assertVisible: "Sign up or log in" From cf02c8d48a109a8086845d9f1e045f432967ce32 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Fri, 24 Jan 2025 11:53:54 +0100 Subject: [PATCH 27/60] move launch args to real deps for now --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3a8ba1db9e7..ff266baaea6 100644 --- a/package.json +++ b/package.json @@ -171,6 +171,7 @@ "react-native-image-crop-picker": "0.41.6", "react-native-in-app-review": "4.3.3", "react-native-keychain": "8.0.0", + "react-native-launch-arguments": "4.0.4", "react-native-linear-gradient": "2.8.3", "react-native-localize": "2.1.3", "react-native-pager-view": "6.5.0", @@ -304,7 +305,6 @@ "prop-types": "15.7.2", "pull-lock": "1.0.0", "react-dom": "17.0.2", - "react-native-launch-arguments": "4.0.4", "react-relay-network-modern": "6.2.2", "react-test-renderer": "18.1.0", "reactotron-react-native": "5.1.7", From bcacdde6b7845858424237a3ed3e69f360581ba0 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Fri, 24 Jan 2025 11:56:18 +0100 Subject: [PATCH 28/60] remove dev check for now --- src/app/App.tsx | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/app/App.tsx b/src/app/App.tsx index d94a43ee22a..90111630028 100644 --- a/src/app/App.tsx +++ b/src/app/App.tsx @@ -49,23 +49,25 @@ if (__DEV__) { require("../../ReactotronConfig.js") } -if (__DEV__) { - const { LaunchArguments } = require("react-native-launch-arguments") - const args = LaunchArguments.value() - const email = args.email - const password = args.password - const shouldSignOut = args.shouldSignOut - if (email && password) { - GlobalStore.actions.auth.signIn({ - oauthProvider: "email", - oauthMode: "email", - email, - password, - }) - } else if (shouldSignOut) { - GlobalStore.actions.auth.signOut() - } +// TODO: We should not have this installed as a dependency in the app +// figure out how to get this conditionally working for maestro builds +// if (__DEV__) { +const { LaunchArguments } = require("react-native-launch-arguments") +const args = LaunchArguments.value() +const email = args.email +const password = args.password +const shouldSignOut = args.shouldSignOut +if (email && password) { + GlobalStore.actions.auth.signIn({ + oauthProvider: "email", + oauthMode: "email", + email, + password, + }) +} else if (shouldSignOut) { + GlobalStore.actions.auth.signOut() } +// } // Sentry must be setup early in the app lifecycle to hook into navigation const debugSentry = unsafe_getDevToggle("DTDebugSentry") From 65c306396771feae9c05e3bb5e7a33bf1f3d76ac Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Fri, 24 Jan 2025 13:01:19 +0100 Subject: [PATCH 29/60] move maestro launch vals to hook to make more reliable, comment out problematic native module for now --- src/app/App.tsx | 23 ++----------- src/app/store/AuthModel.ts | 7 ++-- .../devTools/useMaestroInitialization.ts | 34 +++++++++++++++++++ 3 files changed, 41 insertions(+), 23 deletions(-) create mode 100644 src/app/system/devTools/useMaestroInitialization.ts diff --git a/src/app/App.tsx b/src/app/App.tsx index 90111630028..f3a2715823d 100644 --- a/src/app/App.tsx +++ b/src/app/App.tsx @@ -4,6 +4,7 @@ import { Navigation } from "app/Navigation/Navigation" import { GlobalStore, unsafe__getEnvironment, unsafe_getDevToggle } from "app/store/GlobalStore" import { codePushOptions } from "app/system/codepush" import { DevMenuWrapper } from "app/system/devTools/DevMenu/DevMenuWrapper" +import { useMaestroInitialization } from "app/system/devTools/useMaestroInitialization" import { useRageShakeDevMenu } from "app/system/devTools/useRageShakeDevMenu" import { setupSentry } from "app/system/errorReporting/setupSentry" import { usePurgeCacheOnAppUpdate } from "app/system/relay/usePurgeCacheOnAppUpdate" @@ -49,26 +50,6 @@ if (__DEV__) { require("../../ReactotronConfig.js") } -// TODO: We should not have this installed as a dependency in the app -// figure out how to get this conditionally working for maestro builds -// if (__DEV__) { -const { LaunchArguments } = require("react-native-launch-arguments") -const args = LaunchArguments.value() -const email = args.email -const password = args.password -const shouldSignOut = args.shouldSignOut -if (email && password) { - GlobalStore.actions.auth.signIn({ - oauthProvider: "email", - oauthMode: "email", - email, - password, - }) -} else if (shouldSignOut) { - GlobalStore.actions.auth.signOut() -} -// } - // Sentry must be setup early in the app lifecycle to hook into navigation const debugSentry = unsafe_getDevToggle("DTDebugSentry") const environment = unsafe__getEnvironment() @@ -86,6 +67,8 @@ if (UIManager.setLayoutAnimationEnabledExperimental) { const Main = () => { useRageShakeDevMenu() + useMaestroInitialization() + useEffect(() => { if (Config.OSS === "true") { return diff --git a/src/app/store/AuthModel.ts b/src/app/store/AuthModel.ts index 86dac9bdb89..eabcb899625 100644 --- a/src/app/store/AuthModel.ts +++ b/src/app/store/AuthModel.ts @@ -1007,9 +1007,10 @@ export const getAuthModel = (): AuthModel => ({ updateExperimentsContext({ userId: undefined }) await Promise.all([ - Platform.OS === "ios" - ? await LegacyNativeModules.ArtsyNativeModule.clearUserData() - : Promise.resolve(), + // TODO: Figure out why this is breaking for Maestro + // Platform.OS === "ios" + // ? await LegacyNativeModules.ArtsyNativeModule.clearUserData() + // : Promise.resolve(), __DEV__ && (await clearNavState()), await signOutGoogle(), LoginManager.logOut(), diff --git a/src/app/system/devTools/useMaestroInitialization.ts b/src/app/system/devTools/useMaestroInitialization.ts new file mode 100644 index 00000000000..25e5c9dba36 --- /dev/null +++ b/src/app/system/devTools/useMaestroInitialization.ts @@ -0,0 +1,34 @@ +import { GlobalStore } from "app/store/GlobalStore" +import { useEffect } from "react" +import { LaunchArguments } from "react-native-launch-arguments" + +interface MaestroLaunchArguments { + email?: string + password?: string + shouldSignOut?: boolean +} + +// TODO: We should not have this installed as a dependency in the app +// figure out how to get this conditionally working for maestro builds +export const useMaestroInitialization = () => { + useEffect(() => { + const args = LaunchArguments.value() + console.log("LaunchArgs: ", args) + const email = args.email + const password = args.password + const shouldSignOut = args.shouldSignOut + + if (email && password) { + console.log("LaunchArgs: Signing in with email and password") + GlobalStore.actions.auth.signIn({ + oauthProvider: "email", + oauthMode: "email", + email, + password, + }) + } else if (shouldSignOut) { + console.log("LaunchArgs: Signing out") + GlobalStore.actions.auth.signOut() + } + }, []) +} From 4fe9759c42e2107c710793b7135a686ac131604e Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Fri, 24 Jan 2025 13:15:53 +0100 Subject: [PATCH 30/60] script to workaround xarg exit code behavior --- .circleci/config.yml | 5 +---- run_maestro_shard.sh | 8 ++++++++ 2 files changed, 9 insertions(+), 4 deletions(-) create mode 100755 run_maestro_shard.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index 185473ce715..d87d934ae0c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -245,10 +245,7 @@ jobs: - run: name: Run Maestro Tests no_output_timeout: 25m - command: | - TEST_FILES=$(find e2e -name "*.yml" | sort | awk "NR % ${CIRCLE_NODE_TOTAL} == ${CIRCLE_NODE_INDEX}") - echo "$TEST_FILES" | xargs -n 1 maestro test - + command: ./run_maestro_shard.sh deploy-nightly-beta: environment: BUNDLE_PATH: .vendor diff --git a/run_maestro_shard.sh b/run_maestro_shard.sh new file mode 100755 index 00000000000..8c6203baa92 --- /dev/null +++ b/run_maestro_shard.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +TEST_FILES=$(find e2e -name "*.yml" | sort | awk "NR % ${CIRCLE_NODE_TOTAL} == ${CIRCLE_NODE_INDEX}") + +EXIT_CODE=0 +echo "$TEST_FILES" | xargs -n 1 -I {} bash -c "maestro test {} || EXIT_CODE=$?" +echo "Final Exit Code: $EXIT_CODE" +exit $EXIT_CODE \ No newline at end of file From 4ebaf9fa8325fc41a62e790dbe6d7638fbf4ef6a Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Fri, 24 Jan 2025 13:18:07 +0100 Subject: [PATCH 31/60] only sign out if currently signed in to prevent ui breakage --- src/app/system/devTools/useMaestroInitialization.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/app/system/devTools/useMaestroInitialization.ts b/src/app/system/devTools/useMaestroInitialization.ts index 25e5c9dba36..5367f8f65d9 100644 --- a/src/app/system/devTools/useMaestroInitialization.ts +++ b/src/app/system/devTools/useMaestroInitialization.ts @@ -11,6 +11,8 @@ interface MaestroLaunchArguments { // TODO: We should not have this installed as a dependency in the app // figure out how to get this conditionally working for maestro builds export const useMaestroInitialization = () => { + const isLoggedIn = GlobalStore.useAppState((state) => !!state.auth.userAccessToken) + useEffect(() => { const args = LaunchArguments.value() console.log("LaunchArgs: ", args) @@ -26,9 +28,9 @@ export const useMaestroInitialization = () => { email, password, }) - } else if (shouldSignOut) { + } else if (shouldSignOut && isLoggedIn) { console.log("LaunchArgs: Signing out") GlobalStore.actions.auth.signOut() } - }, []) + }, [isLoggedIn]) } From d5594f235458310690f27b71047344cdb5be527c Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Thu, 22 May 2025 15:09:36 -0300 Subject: [PATCH 32/60] add required appID in config --- e2e/config.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/e2e/config.yml b/e2e/config.yml index ee1543c1aad..75693b68877 100644 --- a/e2e/config.yml +++ b/e2e/config.yml @@ -1,2 +1,4 @@ +appId: net.artsy.artsy +--- flows: - "flows/*" From 7ce7aaf36b6316cce817d8216ac6ec1a79a9db4c Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Thu, 22 May 2025 15:42:44 -0300 Subject: [PATCH 33/60] run tests in sequence to avoid exit code not being propogated --- run_maestro_shard.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/run_maestro_shard.sh b/run_maestro_shard.sh index 8c6203baa92..3d92cd3810e 100755 --- a/run_maestro_shard.sh +++ b/run_maestro_shard.sh @@ -3,6 +3,14 @@ TEST_FILES=$(find e2e -name "*.yml" | sort | awk "NR % ${CIRCLE_NODE_TOTAL} == ${CIRCLE_NODE_INDEX}") EXIT_CODE=0 -echo "$TEST_FILES" | xargs -n 1 -I {} bash -c "maestro test {} || EXIT_CODE=$?" + +for TEST_FILE in $TEST_FILES; do + echo "Running test: $TEST_FILE" + maestro test "$TEST_FILE" + if [ $? -ne 0 ]; then + EXIT_CODE=1 + fi +done + echo "Final Exit Code: $EXIT_CODE" exit $EXIT_CODE \ No newline at end of file From dbdd7a8cca764076455bea2fde8d5d523609bc06 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Thu, 22 May 2025 15:43:15 -0300 Subject: [PATCH 34/60] comment auth model lint error for now --- src/app/store/AuthModel.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/store/AuthModel.ts b/src/app/store/AuthModel.ts index 199a62ec64f..d111cc31b4e 100644 --- a/src/app/store/AuthModel.ts +++ b/src/app/store/AuthModel.ts @@ -5,7 +5,7 @@ import AsyncStorage from "@react-native-async-storage/async-storage" import CookieManager from "@react-native-cookies/cookies" import { GoogleSignin, statusCodes } from "@react-native-google-signin/google-signin" import * as Sentry from "@sentry/react-native" -import { LegacyNativeModules } from "app/NativeModules/LegacyNativeModules" +// import { LegacyNativeModules } from "app/NativeModules/LegacyNativeModules" import { clearNavState } from "app/system/navigation/useReloadedDevNavigationState" import { _globalCacheRef } from "app/system/relay/defaultEnvironment" import { From ecf8044e553ea570fbf65b7b00d1f62593203b3b Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Thu, 22 May 2025 15:59:02 -0300 Subject: [PATCH 35/60] maestro init not dependent on login state, to avoid double sign out --- src/app/system/devTools/useMaestroInitialization.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/system/devTools/useMaestroInitialization.ts b/src/app/system/devTools/useMaestroInitialization.ts index 5367f8f65d9..ab11ddb1ad9 100644 --- a/src/app/system/devTools/useMaestroInitialization.ts +++ b/src/app/system/devTools/useMaestroInitialization.ts @@ -32,5 +32,5 @@ export const useMaestroInitialization = () => { console.log("LaunchArgs: Signing out") GlobalStore.actions.auth.signOut() } - }, [isLoggedIn]) + }, []) } From 016cd6af648d5681f31d75d6e89cc0249724df2a Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Wed, 28 May 2025 10:33:29 -0300 Subject: [PATCH 36/60] remove conditional check, assert we are in signup flow Co-authored-by: George --- e2e/flows/signup.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/e2e/flows/signup.yml b/e2e/flows/signup.yml index cb0f5025248..82e1a71bbe4 100644 --- a/e2e/flows/signup.yml +++ b/e2e/flows/signup.yml @@ -10,18 +10,12 @@ appId: ${MAESTRO_APP_ID} - tapOn: "Email Input" - inputText: ${output.signup.email} - tapOn: "Continue.*" +- assertVisible: "Welcome to Artsy" - inputText: ${output.signup.password} - tapOn: "Continue.*" - inputText: "Test McTest" - runFlow: - when: - platform: iOS commands: - tapOn: point: 15%,36% -- runFlow: - when: - platform: Android - commands: - - tapOn: "Accept terms and privacy policy, Check this element to accept Artsy's terms and privacy policy" - tapOn: "Continue.*" From b54fd42b1b1a1ec39e0dd5bc8285c557f1160f8b Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Thu, 29 May 2025 14:33:44 -0300 Subject: [PATCH 37/60] revert me: recaptcha debugging --- src/app/Components/Recaptcha/Recaptcha.tsx | 3 + .../Components/Recaptcha/RecaptchaWebView.tsx | 348 ++++++++++++++++-- .../Auth2/scenes/LoginWelcomeStep.tsx | 7 + src/app/store/AuthModel.ts | 9 +- 4 files changed, 342 insertions(+), 25 deletions(-) diff --git a/src/app/Components/Recaptcha/Recaptcha.tsx b/src/app/Components/Recaptcha/Recaptcha.tsx index 18b0faef123..ddbef3a73db 100644 --- a/src/app/Components/Recaptcha/Recaptcha.tsx +++ b/src/app/Components/Recaptcha/Recaptcha.tsx @@ -10,6 +10,7 @@ export const useRecaptcha = ({ source, action }: UseRecaptchaProps) => { const [state, setState] = useState() const handleOnToken = (token: string) => { + console.log(`[Recaptcha token received for source ${source} and action ${action}]`, token) setToken(token) } @@ -27,6 +28,8 @@ export const useRecaptcha = ({ source, action }: UseRecaptchaProps) => { return null } + console.log(`[Recaptcha] rendering for source ${source} and action ${action}`) + return ( diff --git a/src/app/Components/Recaptcha/RecaptchaWebView.tsx b/src/app/Components/Recaptcha/RecaptchaWebView.tsx index 67854499ba0..a3493197c1c 100644 --- a/src/app/Components/Recaptcha/RecaptchaWebView.tsx +++ b/src/app/Components/Recaptcha/RecaptchaWebView.tsx @@ -23,37 +23,76 @@ export const RecaptchaWebView: FC = ({ const recaptchaKey = !isStaging ? Keys.secureFor("RECAPTCHA_KEY_PRODUCTION") : Keys.secureFor("RECAPTCHA_KEY_STAGING") + const baseUrl = !isStaging ? "https://artsy.net/" : "https://staging.artsy.net/" + console.log( + `[RecaptchaWebView] rendering for action ${action} with recaptchaKey: ${recaptchaKey} and baseUrl: ${baseUrl}` + ) + + // const handleOnMessage = (e: WebViewMessageEvent) => { + // const message = getMessage(e) + // console.log(`[RecaptchaWebView] received message for action ${action}:`, message) + // if (message?.type === "token") { + // onToken(message.payload) + // return + // } + // if (message?.type === "error") { + // onError?.(message.payload) + // return + // } + // } + const handleOnMessage = (e: WebViewMessageEvent) => { - const message = getMessage(e) - if (message?.type === "token") { - onToken(message.payload) - return - } - if (message?.type === "error") { - onError?.(message.payload) - return + try { + const message = JSON.parse(e.nativeEvent.data) + console.log("[RecaptchaWebView] Message received:", message) + + if (message.type === "token") { + onToken(message.payload) + } else if (message.type === "error") { + onError?.(message.payload) + } else if (message.type === "READY") { + console.log("[RecaptchaWebView] Recaptcha is ready") + } else if (message.type === "script-load-success") { + console.log("[RecaptchaWebView] Script loaded successfully") + } else if (message.type === "script-load-failure") { + console.error("[RecaptchaWebView] Script failed to load:", message.payload) + } + } catch (err) { + console.log("Failed to parse message from WebView:", err) } } + console.log(`[RecaptchaWebView] rendering`) return ( onError?.(e.nativeEvent.description)} onLoad={() => onLoad?.()} - onMessage={handleOnMessage} + onMessage={(e) => { + console.log(`[RecaptchaWebView] onMessage called for action ${action}`) + handleOnMessage(e) + }} allowFileAccessFromFileURLs javaScriptCanOpenWindowsAutomatically + onLoadStart={() => { + console.log(`[RecaptchaWebView] onLoadStart called for action ${action}`) + }} onShouldStartLoadWithRequest={(e: ShouldStartLoadRequest) => { + console.log( + `[RecaptchaWebView] onShouldStartLoadWithRequest called for action ${action}`, + e + ) if ( e.url.startsWith("https://www.google.com/recaptcha") || e.url.startsWith("https://staging.artsy.net") || @@ -68,28 +107,246 @@ export const RecaptchaWebView: FC = ({ ) } -const html = (recaptchaKey: string, action: string) => ` +// const html = (recaptchaKey: string, action: string) => ` +// +// +// +// +// +// +//

Loading reCAPTCHA...

+// +// +// +// +// ` + +const simplehtml = () => ` + + + +

Hello from WebView

+ + + +` + +const slightyBetterHtml = () => ` +

Trying to load reCAPTCHA script...

+ + + ` + +const evenBetterHtml = (recaptchaKey: string, action: string) => ` + + + +

Loading reCAPTCHA with your key...

+ + + +` + +const againBetterHtml = (recaptchaKey: string, action: string) => ` + + + - +

Loading reCAPTCHA script...

+ ` -const loadRecaptcha = (recaptchaKey: string, action: string) => ` - grecaptcha.ready(function () { - grecaptcha.execute("${recaptchaKey}", { action: "${action}" }) - .then(function(token) { - window.ReactNativeWebView?.postMessage(JSON.stringify({ payload: token, type: "token" })) - }) - .catch(function (error) { - window.ReactNativeWebView?.postMessage(JSON.stringify({ payload: error?.message, type: "error" })) - }) - }) +const lodashHtml = () => ` + + + + + + +` + +const v3html = (recaptchaKey: string, action: string) => ` + + + + + + +

Loading reCAPTCHA v3 script with key...

+ + + + ` type Message = { payload: string; type: "token" | "error" } @@ -106,3 +363,46 @@ const getMessage = (event: WebViewMessageEvent): null | Message => { return null } } + +// const loadRecaptchaOld = (recaptchaKey: string, action: string) => ` +// alert("[Recaptcha] Script started for action: ${action}"); +// grecaptcha.ready(function () { +// alert("[Recaptcha] grecaptcha.ready triggered for action: ${action}"); +// grecaptcha.execute("${recaptchaKey}", { action: "${action}" }) +// .then(function(token) { +// alert("[Recaptcha] Token received for action: ${action}", token); +// window.ReactNativeWebView?.postMessage(JSON.stringify({ payload: token, type: "token" })) +// }) +// .catch(function (error) { +// alert("[Recaptcha] Error received for action: ${action}", error); +// window.ReactNativeWebView?.postMessage(JSON.stringify({ payload: error?.message, type: "error" })) +// }) +// }) +// ` + +// const loadRecaptcha = (recaptchaKey: string, action: string) => ` +// try { +// alert("[Recaptcha] Script started for action: ${action}"); + +// // if (typeof grecaptcha === 'undefined') { +// // alert("[Recaptcha] grecaptcha is undefined — script may not have loaded"); +// // return; +// // } + +// grecaptcha.ready(function () { +// alert("[Recaptcha] grecaptcha.ready triggered for action: ${action}"); + +// grecaptcha.execute("${recaptchaKey}", { action: "${action}" }) +// .then(function(token) { +// alert("[Recaptcha] Token received for action: ${action}\\n" + token); +// window.ReactNativeWebView?.postMessage(JSON.stringify({ payload: token, type: "token" })); +// }) +// .catch(function (error) { +// alert("[Recaptcha] Error received for action: ${action}\\n" + (error?.message || error)); +// window.ReactNativeWebView?.postMessage(JSON.stringify({ payload: error?.message, type: "error" })); +// }); +// }); +// } catch (e) { +// alert("[Recaptcha] Exception caught:\\n" + (e?.message || e)); +// } +// ` diff --git a/src/app/Scenes/Onboarding/Auth2/scenes/LoginWelcomeStep.tsx b/src/app/Scenes/Onboarding/Auth2/scenes/LoginWelcomeStep.tsx index 956c751e6f1..765dd93e529 100644 --- a/src/app/Scenes/Onboarding/Auth2/scenes/LoginWelcomeStep.tsx +++ b/src/app/Scenes/Onboarding/Auth2/scenes/LoginWelcomeStep.tsx @@ -55,6 +55,9 @@ export const LoginWelcomeStep: React.FC = () => { onSubmit={async ({ email }, { resetForm }) => { // FIXME if (!token) { + console.log( + `[LoginWelcomeStep] didn't receive a token, navigating to LoginPasswordStep` + ) navigation.navigate({ name: "LoginPasswordStep", params: { email, showSignUpLink: true }, @@ -62,13 +65,17 @@ export const LoginWelcomeStep: React.FC = () => { return } + console.log(`[LoginWelcomeStep] Verifying user with email: ${email} and token: ${token}`) const res = await GlobalStore.actions.auth.verifyUser({ email, recaptchaToken: token }) if (res === "user_exists") { + console.log(`[LoginWelcomeStep] User exists, navigating to LoginPasswordStep`) navigation.navigate({ name: "LoginPasswordStep", params: { email } }) } else if (res === "user_does_not_exist") { + console.log(`[LoginWelcomeStep] User does not exist, navigating to SignUpPasswordStep`) navigation.navigate({ name: "SignUpPasswordStep", params: { email } }) } else if (res === "something_went_wrong") { + console.log(`[LoginWelcomeStep] Something went wrong, navigating to LoginPasswordStep`) navigation.navigate({ name: "LoginPasswordStep", params: { email, showSignUpLink: true }, diff --git a/src/app/store/AuthModel.ts b/src/app/store/AuthModel.ts index d111cc31b4e..f4422530ed5 100644 --- a/src/app/store/AuthModel.ts +++ b/src/app/store/AuthModel.ts @@ -1023,15 +1023,22 @@ export const getAuthModel = (): AuthModel => ({ }) } catch (error) { Sentry.captureMessage(`AuthModel verifyUser error ${error}`) + console.log(`[AuthModel] verifyUser error: ${error}`) return "something_went_wrong" } if (result.status !== 201) { Sentry.captureMessage(`AuthModel verifyUser result status ${result.status}`) + const json = await result.json() + console.log(`[AuthModel] verifyUser result:\n${JSON.stringify(json, null, 2)}`) return "something_went_wrong" } - const { exists } = await result.json() + const json = await result.json() + + const exists = json.exists + + console.log(`[AuthModel] verifyUser result: ${json}`) if (exists) { return "user_exists" From 6bfaa90b19480d8fb7df977f45773b2749cea98f Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Thu, 29 May 2025 14:33:53 -0300 Subject: [PATCH 38/60] Revert "revert me: recaptcha debugging" This reverts commit b54fd42b1b1a1ec39e0dd5bc8285c557f1160f8b. --- src/app/Components/Recaptcha/Recaptcha.tsx | 3 - .../Components/Recaptcha/RecaptchaWebView.tsx | 348 ++---------------- .../Auth2/scenes/LoginWelcomeStep.tsx | 7 - src/app/store/AuthModel.ts | 9 +- 4 files changed, 25 insertions(+), 342 deletions(-) diff --git a/src/app/Components/Recaptcha/Recaptcha.tsx b/src/app/Components/Recaptcha/Recaptcha.tsx index ddbef3a73db..18b0faef123 100644 --- a/src/app/Components/Recaptcha/Recaptcha.tsx +++ b/src/app/Components/Recaptcha/Recaptcha.tsx @@ -10,7 +10,6 @@ export const useRecaptcha = ({ source, action }: UseRecaptchaProps) => { const [state, setState] = useState() const handleOnToken = (token: string) => { - console.log(`[Recaptcha token received for source ${source} and action ${action}]`, token) setToken(token) } @@ -28,8 +27,6 @@ export const useRecaptcha = ({ source, action }: UseRecaptchaProps) => { return null } - console.log(`[Recaptcha] rendering for source ${source} and action ${action}`) - return ( diff --git a/src/app/Components/Recaptcha/RecaptchaWebView.tsx b/src/app/Components/Recaptcha/RecaptchaWebView.tsx index a3493197c1c..67854499ba0 100644 --- a/src/app/Components/Recaptcha/RecaptchaWebView.tsx +++ b/src/app/Components/Recaptcha/RecaptchaWebView.tsx @@ -23,76 +23,37 @@ export const RecaptchaWebView: FC = ({ const recaptchaKey = !isStaging ? Keys.secureFor("RECAPTCHA_KEY_PRODUCTION") : Keys.secureFor("RECAPTCHA_KEY_STAGING") - const baseUrl = !isStaging ? "https://artsy.net/" : "https://staging.artsy.net/" - console.log( - `[RecaptchaWebView] rendering for action ${action} with recaptchaKey: ${recaptchaKey} and baseUrl: ${baseUrl}` - ) - - // const handleOnMessage = (e: WebViewMessageEvent) => { - // const message = getMessage(e) - // console.log(`[RecaptchaWebView] received message for action ${action}:`, message) - // if (message?.type === "token") { - // onToken(message.payload) - // return - // } - // if (message?.type === "error") { - // onError?.(message.payload) - // return - // } - // } - const handleOnMessage = (e: WebViewMessageEvent) => { - try { - const message = JSON.parse(e.nativeEvent.data) - console.log("[RecaptchaWebView] Message received:", message) - - if (message.type === "token") { - onToken(message.payload) - } else if (message.type === "error") { - onError?.(message.payload) - } else if (message.type === "READY") { - console.log("[RecaptchaWebView] Recaptcha is ready") - } else if (message.type === "script-load-success") { - console.log("[RecaptchaWebView] Script loaded successfully") - } else if (message.type === "script-load-failure") { - console.error("[RecaptchaWebView] Script failed to load:", message.payload) - } - } catch (err) { - console.log("Failed to parse message from WebView:", err) + const message = getMessage(e) + if (message?.type === "token") { + onToken(message.payload) + return + } + if (message?.type === "error") { + onError?.(message.payload) + return } } - console.log(`[RecaptchaWebView] rendering`) return ( onError?.(e.nativeEvent.description)} onLoad={() => onLoad?.()} - onMessage={(e) => { - console.log(`[RecaptchaWebView] onMessage called for action ${action}`) - handleOnMessage(e) - }} + onMessage={handleOnMessage} allowFileAccessFromFileURLs javaScriptCanOpenWindowsAutomatically - onLoadStart={() => { - console.log(`[RecaptchaWebView] onLoadStart called for action ${action}`) - }} onShouldStartLoadWithRequest={(e: ShouldStartLoadRequest) => { - console.log( - `[RecaptchaWebView] onShouldStartLoadWithRequest called for action ${action}`, - e - ) if ( e.url.startsWith("https://www.google.com/recaptcha") || e.url.startsWith("https://staging.artsy.net") || @@ -107,246 +68,28 @@ export const RecaptchaWebView: FC = ({ ) } -// const html = (recaptchaKey: string, action: string) => ` -// -// -// -// -// -// -//

Loading reCAPTCHA...

-// -// -// -// -// ` - -const simplehtml = () => ` - - - -

Hello from WebView

- - - -` - -const slightyBetterHtml = () => ` -

Trying to load reCAPTCHA script...

- - - ` - -const evenBetterHtml = (recaptchaKey: string, action: string) => ` - - - -

Loading reCAPTCHA with your key...

- - - -` - -const againBetterHtml = (recaptchaKey: string, action: string) => ` +const html = (recaptchaKey: string, action: string) => ` - - - -

Loading reCAPTCHA script...

- + ` -const lodashHtml = () => ` - - - - - - -` - -const v3html = (recaptchaKey: string, action: string) => ` - - - - - - -

Loading reCAPTCHA v3 script with key...

- - - - +const loadRecaptcha = (recaptchaKey: string, action: string) => ` + grecaptcha.ready(function () { + grecaptcha.execute("${recaptchaKey}", { action: "${action}" }) + .then(function(token) { + window.ReactNativeWebView?.postMessage(JSON.stringify({ payload: token, type: "token" })) + }) + .catch(function (error) { + window.ReactNativeWebView?.postMessage(JSON.stringify({ payload: error?.message, type: "error" })) + }) + }) ` type Message = { payload: string; type: "token" | "error" } @@ -363,46 +106,3 @@ const getMessage = (event: WebViewMessageEvent): null | Message => { return null } } - -// const loadRecaptchaOld = (recaptchaKey: string, action: string) => ` -// alert("[Recaptcha] Script started for action: ${action}"); -// grecaptcha.ready(function () { -// alert("[Recaptcha] grecaptcha.ready triggered for action: ${action}"); -// grecaptcha.execute("${recaptchaKey}", { action: "${action}" }) -// .then(function(token) { -// alert("[Recaptcha] Token received for action: ${action}", token); -// window.ReactNativeWebView?.postMessage(JSON.stringify({ payload: token, type: "token" })) -// }) -// .catch(function (error) { -// alert("[Recaptcha] Error received for action: ${action}", error); -// window.ReactNativeWebView?.postMessage(JSON.stringify({ payload: error?.message, type: "error" })) -// }) -// }) -// ` - -// const loadRecaptcha = (recaptchaKey: string, action: string) => ` -// try { -// alert("[Recaptcha] Script started for action: ${action}"); - -// // if (typeof grecaptcha === 'undefined') { -// // alert("[Recaptcha] grecaptcha is undefined — script may not have loaded"); -// // return; -// // } - -// grecaptcha.ready(function () { -// alert("[Recaptcha] grecaptcha.ready triggered for action: ${action}"); - -// grecaptcha.execute("${recaptchaKey}", { action: "${action}" }) -// .then(function(token) { -// alert("[Recaptcha] Token received for action: ${action}\\n" + token); -// window.ReactNativeWebView?.postMessage(JSON.stringify({ payload: token, type: "token" })); -// }) -// .catch(function (error) { -// alert("[Recaptcha] Error received for action: ${action}\\n" + (error?.message || error)); -// window.ReactNativeWebView?.postMessage(JSON.stringify({ payload: error?.message, type: "error" })); -// }); -// }); -// } catch (e) { -// alert("[Recaptcha] Exception caught:\\n" + (e?.message || e)); -// } -// ` diff --git a/src/app/Scenes/Onboarding/Auth2/scenes/LoginWelcomeStep.tsx b/src/app/Scenes/Onboarding/Auth2/scenes/LoginWelcomeStep.tsx index 765dd93e529..956c751e6f1 100644 --- a/src/app/Scenes/Onboarding/Auth2/scenes/LoginWelcomeStep.tsx +++ b/src/app/Scenes/Onboarding/Auth2/scenes/LoginWelcomeStep.tsx @@ -55,9 +55,6 @@ export const LoginWelcomeStep: React.FC = () => { onSubmit={async ({ email }, { resetForm }) => { // FIXME if (!token) { - console.log( - `[LoginWelcomeStep] didn't receive a token, navigating to LoginPasswordStep` - ) navigation.navigate({ name: "LoginPasswordStep", params: { email, showSignUpLink: true }, @@ -65,17 +62,13 @@ export const LoginWelcomeStep: React.FC = () => { return } - console.log(`[LoginWelcomeStep] Verifying user with email: ${email} and token: ${token}`) const res = await GlobalStore.actions.auth.verifyUser({ email, recaptchaToken: token }) if (res === "user_exists") { - console.log(`[LoginWelcomeStep] User exists, navigating to LoginPasswordStep`) navigation.navigate({ name: "LoginPasswordStep", params: { email } }) } else if (res === "user_does_not_exist") { - console.log(`[LoginWelcomeStep] User does not exist, navigating to SignUpPasswordStep`) navigation.navigate({ name: "SignUpPasswordStep", params: { email } }) } else if (res === "something_went_wrong") { - console.log(`[LoginWelcomeStep] Something went wrong, navigating to LoginPasswordStep`) navigation.navigate({ name: "LoginPasswordStep", params: { email, showSignUpLink: true }, diff --git a/src/app/store/AuthModel.ts b/src/app/store/AuthModel.ts index f4422530ed5..d111cc31b4e 100644 --- a/src/app/store/AuthModel.ts +++ b/src/app/store/AuthModel.ts @@ -1023,22 +1023,15 @@ export const getAuthModel = (): AuthModel => ({ }) } catch (error) { Sentry.captureMessage(`AuthModel verifyUser error ${error}`) - console.log(`[AuthModel] verifyUser error: ${error}`) return "something_went_wrong" } if (result.status !== 201) { Sentry.captureMessage(`AuthModel verifyUser result status ${result.status}`) - const json = await result.json() - console.log(`[AuthModel] verifyUser result:\n${JSON.stringify(json, null, 2)}`) return "something_went_wrong" } - const json = await result.json() - - const exists = json.exists - - console.log(`[AuthModel] verifyUser result: ${json}`) + const { exists } = await result.json() if (exists) { return "user_exists" From 263aaaa90c5c50b8a157c7d9355c407c3624dd76 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Thu, 29 May 2025 14:47:12 -0300 Subject: [PATCH 39/60] fix deeplink assertion --- e2e/flows/deeplinks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/flows/deeplinks.yml b/e2e/flows/deeplinks.yml index 61feee3f7b0..d2095550b5f 100644 --- a/e2e/flows/deeplinks.yml +++ b/e2e/flows/deeplinks.yml @@ -26,4 +26,4 @@ appId: ${MAESTRO_APP_ID} - openLink: link: "https://email-link.artsy.net/ls/click?upn=u001.XPbk8dXjc6dwd18Yq2uPM3eTWB4YbDUmeJTAXXTF513sTSKEFRIPxrFgGj8gd2LN9AcRIza5p2-2Fi0huqjv6GWgdnpwA-2FRyTEIYA-2BT1-2F0josxHnYTzJpKeJEmkfzDQlMEY9y6FknqDddY-2BKmm5qtTrTIF2hxySbdUboaYf5ofK-2Bj-2FgSolzBiLvvzai-2FmvjWbSpNpJHWATexQixwLakesmmZUBoRoLkCnxs59pBxJPbB3JZyP13cv77lbfn1WzJ86fiW-2B5MQcd2qss7wLGBI-2BZuy-2FxDkbFuDzpfYPDlaUs1-2BuyO9rqleUCwXPEuyWXZ3aGJrh-_dWIRBTTKlL2IhQqV5a1Cy38Sd4xylePmkTfQkXpdWOLZbG0vcWuzG-2BSSjZ7xaSUgPR0lxFBD0Zz4mpyMqiSRd7GblcbPN8eH0NYfUK6pmADWc2UoFXyJdeq-2F-2BOyOeWlS7O-2FOrHgB9-2BOGtV1nkIFPq97vJTNmWtBMDOt77SsursARR1LHG7CnzBEedV5yll40aEh9LTjA47-2BfpvonTwdxvYfd6ZWsZN2uRczvCs34ipSKUClLSzq0xCn8IjAixssMm2IreBk6LmNzHPC1YLqmZ77pv0qTxX095mxh8mk7f9rJJ8Tg1fyfRFriXGsQqgHlY-2BqTf2aAU6LS9NVXirqdp20-2BHXhzUZbaCnkQNASABts91iKoZaDeV4xnYuuo3L-2F8" autoVerify: false -- assertVisible: "Jaune 2_40, 2023" +- assertVisible: "The artwork you were looking for isn't available." From d5bd669863268b18488319686805195c2fc179ef Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Thu, 29 May 2025 14:47:39 -0300 Subject: [PATCH 40/60] make sure brokenflows are not run --- run_maestro_shard.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run_maestro_shard.sh b/run_maestro_shard.sh index 3d92cd3810e..802d65e8949 100755 --- a/run_maestro_shard.sh +++ b/run_maestro_shard.sh @@ -1,6 +1,6 @@ #!/bin/bash -TEST_FILES=$(find e2e -name "*.yml" | sort | awk "NR % ${CIRCLE_NODE_TOTAL} == ${CIRCLE_NODE_INDEX}") +TEST_FILES=$(find e2e/flows -name "*.yml" | sort | awk "NR % ${CIRCLE_NODE_TOTAL} == ${CIRCLE_NODE_INDEX}") EXIT_CODE=0 From a9baec8d9f0b7d28cb5a16f46c433a1c5cbf25ae Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Thu, 29 May 2025 14:54:30 -0300 Subject: [PATCH 41/60] quick login for deeplink test --- e2e/flows/deeplinks.yml | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/e2e/flows/deeplinks.yml b/e2e/flows/deeplinks.yml index d2095550b5f..601785a866e 100644 --- a/e2e/flows/deeplinks.yml +++ b/e2e/flows/deeplinks.yml @@ -2,16 +2,10 @@ appId: ${MAESTRO_APP_ID} --- - launchApp: clearState: false -- runFlow: - when: - visible: "Sign up or log in" - commands: - - tapOn: "Email Input" - - inputText: ${MAESTRO_TEST_EMAIL} - - tapOn: "Continue.*" - - inputText: ${MAESTRO_TEST_PASSWORD} - - tapOn: "Continue.*" - - assertVisible: "New Works for You" + arguments: + email: ${MAESTRO_TEST_EMAIL} + password: ${MAESTRO_TEST_PASSWORD} +- assertVisible: "New Works for You" - killApp - openLink: link: https://www.artsy.net/artist/kaws From 680591c98e0f145e48cc2e171235e762d7f41d22 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Thu, 29 May 2025 16:02:28 -0300 Subject: [PATCH 42/60] run tests after beta --- .circleci/config.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0225638e291..f27f35af086 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -565,14 +565,17 @@ workflows: jobs: - deploy-nightly-beta - run-nightly-tasks + - run-e2e-tests: + requires: + - deploy-nightly-beta run-e2e: jobs: - run-e2e-tests: - filters: - branches: - only: - - brian/e2e-again + filters: + branches: + only: + - brian/e2e-again flag-check: triggers: From 13711bc305b20345479116cc4d63aac0d051f240 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Thu, 29 May 2025 17:08:38 -0300 Subject: [PATCH 43/60] upload build to s3 and use in maestro tests --- .circleci/config.yml | 3 ++- fastlane/Fastfile | 11 +++++----- fastlane/utility_fastlane.rb | 40 ++++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f27f35af086..dc0470961cd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -225,7 +225,7 @@ jobs: - setup-awscli - run: name: Download app zip - command: aws s3 cp s3://artsy-citadel/eigen/Artsy.zip ./Artsy.zip + command: aws s3 cp s3://artsy-citadel/eigen/builds/ios/Artsy-latest.zip ./Artsy.zip - run: name: Unzip the app command: unzip Artsy.zip @@ -236,6 +236,7 @@ jobs: name: Run Maestro Tests no_output_timeout: 25m command: ./run_maestro_shard.sh + deploy-nightly-beta: environment: BUNDLE_PATH: .vendor diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 2f5dd10d59a..51e4fedf360 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -47,6 +47,7 @@ GIT_REMOTE_ORIGIN_URL = `git config --get remote.origin.url`.chomp S3_PATH = 's3://artsy-citadel/eigen' S3_ANDROID_BUILDS_PATH = S3_PATH + '/builds/android/' +S3_IOS_BUILDS_PATH = S3_PATH + '/builds/ios/' import 'utility_fastlane.rb' import 'sentry_fastlane.rb' @@ -101,6 +102,10 @@ lane :ship_beta_ios do |options| dist_version: bundle_version, platform: 'ios' ) + + s3_upload_ios_build( + app_version: bundle_version + ) end deploy_ios_beta(deployment_target: deployment_target) @@ -361,12 +366,6 @@ lane :create_android_apk do ) end -lane :s3_upload_android_build do |options| - app_version = options[:app_version] - app_path = options[:app_path] - sh('aws s3 cp ' + app_path + ' ' + S3_ANDROID_BUILDS_PATH + app_version.to_s + '.aab') -end - lane :select_android_build do |options| select_message = options[:select_message] || 'release' skip_download = options[:skip_download] || false diff --git a/fastlane/utility_fastlane.rb b/fastlane/utility_fastlane.rb index 9d662bab1a3..2e0480c5930 100644 --- a/fastlane/utility_fastlane.rb +++ b/fastlane/utility_fastlane.rb @@ -70,6 +70,46 @@ ) end +# Build and upload iOS and Android builds to S3 + +lane :s3_upload_ios_build do |options| + UI.message("Uploading iOS build to S3...") + + app_version = options[:app_version] + archive_root = options[:archive_root] || "../archives" + app_name = options[:app_name] || "Artsy" + + # Find latest archive + pattern = File.join(archive_root, "#{app_name}*.xcarchive") + matching_archives = Dir.glob(pattern) + + UI.user_error!("No .xcarchive found matching pattern #{pattern}") unless matching_archives.any? + + latest_archive = matching_archives.max_by { |f| File.mtime(f) } + app_path = File.join(latest_archive, "Products/Applications/#{app_name}.app") + UI.user_error!("App not found at #{app_path}") unless File.exist?(app_path) + + # Create zip + zip_name = "#{app_name}-#{app_version}.zip" + zip_path = File.join(archive_root, zip_name) + latest_zip_path = File.join(archive_root, "#{app_name}-latest.zip") + + sh("zip -r #{zip_path} '#{app_path}'") + FileUtils.cp(zip_path, latest_zip_path) + + # Upload both versioned and "latest" + sh("aws s3 cp #{zip_path} #{S3_IOS_BUILDS_PATH}#{zip_name}") + sh("aws s3 cp #{latest_zip_path} #{S3_IOS_BUILDS_PATH}#{app_name}-latest.zip") + + UI.success("✅ Uploaded #{zip_name} and latest to S3") +end + +lane :s3_upload_android_build do |options| + app_version = options[:app_version] + app_path = options[:app_path] + sh('aws s3 cp ' + app_path + ' ' + S3_ANDROID_BUILDS_PATH + app_version.to_s + '.aab') +end + lane :tag_and_push do |options| # Do a tag, we use a http git remote so we can have push access # as the default remote for circle is read-only From ac120dfd8dffc50023c9d4831264629d072924cb Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Fri, 30 May 2025 11:00:30 -0300 Subject: [PATCH 44/60] gate maestro init behind check --- src/app/system/devTools/useMaestroInitialization.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/app/system/devTools/useMaestroInitialization.ts b/src/app/system/devTools/useMaestroInitialization.ts index ab11ddb1ad9..d2e6f8404f4 100644 --- a/src/app/system/devTools/useMaestroInitialization.ts +++ b/src/app/system/devTools/useMaestroInitialization.ts @@ -1,3 +1,4 @@ +import { ArtsyNativeModule } from "app/NativeModules/ArtsyNativeModule" import { GlobalStore } from "app/store/GlobalStore" import { useEffect } from "react" import { LaunchArguments } from "react-native-launch-arguments" @@ -8,12 +9,12 @@ interface MaestroLaunchArguments { shouldSignOut?: boolean } -// TODO: We should not have this installed as a dependency in the app -// figure out how to get this conditionally working for maestro builds export const useMaestroInitialization = () => { const isLoggedIn = GlobalStore.useAppState((state) => !!state.auth.userAccessToken) useEffect(() => { + if (!ArtsyNativeModule.isBetaOrDev) return + const args = LaunchArguments.value() console.log("LaunchArgs: ", args) const email = args.email From 60d10dd3a96bdef25d41bb3b75bacdde29b58785 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Fri, 30 May 2025 11:32:58 -0300 Subject: [PATCH 45/60] remove logs --- src/app/system/devTools/useMaestroInitialization.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/app/system/devTools/useMaestroInitialization.ts b/src/app/system/devTools/useMaestroInitialization.ts index d2e6f8404f4..078b039a1ea 100644 --- a/src/app/system/devTools/useMaestroInitialization.ts +++ b/src/app/system/devTools/useMaestroInitialization.ts @@ -16,13 +16,11 @@ export const useMaestroInitialization = () => { if (!ArtsyNativeModule.isBetaOrDev) return const args = LaunchArguments.value() - console.log("LaunchArgs: ", args) const email = args.email const password = args.password const shouldSignOut = args.shouldSignOut if (email && password) { - console.log("LaunchArgs: Signing in with email and password") GlobalStore.actions.auth.signIn({ oauthProvider: "email", oauthMode: "email", @@ -30,7 +28,6 @@ export const useMaestroInitialization = () => { password, }) } else if (shouldSignOut && isLoggedIn) { - console.log("LaunchArgs: Signing out") GlobalStore.actions.auth.signOut() } }, []) From d78b35ddf7424961fb20a298bb684dea5a8d5d36 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Fri, 30 May 2025 11:40:04 -0300 Subject: [PATCH 46/60] test beta + e2e workflow --- .circleci/config.yml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index dc0470961cd..39983119cbd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -570,14 +570,29 @@ workflows: requires: - deploy-nightly-beta - run-e2e: + run-e2e-beta-test: jobs: + - deploy-nightly-beta: + filters: + branches: + only: + - brian/e2e-again - run-e2e-tests: + requires: + - deploy-nightly-beta filters: branches: only: - brian/e2e-again + # run-e2e: + # jobs: + # - run-e2e-tests: + # filters: + # branches: + # only: + # - brian/e2e-again + flag-check: triggers: - schedule: From acfde67c43fe377c86ec95b7446e45a5421366ab Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Fri, 30 May 2025 12:47:30 -0300 Subject: [PATCH 47/60] check to avoid crash when native module called early --- .../Networking/API_Modules/ArtsyAPI+DeviceTokens.m | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ios/Artsy/Networking/API_Modules/ArtsyAPI+DeviceTokens.m b/ios/Artsy/Networking/API_Modules/ArtsyAPI+DeviceTokens.m index 9ea54b05ef0..b9b3cda3069 100644 --- a/ios/Artsy/Networking/API_Modules/ArtsyAPI+DeviceTokens.m +++ b/ios/Artsy/Networking/API_Modules/ArtsyAPI+DeviceTokens.m @@ -13,6 +13,13 @@ + (AFHTTPRequestOperation *)setAPNTokenForCurrentDevice:(NSString *)token succes if (token && name) { NSURLRequest *request = [ARRouter newSetDeviceAPNTokenRequest:token forDevice:name]; + + // TODO: Is it a problem that this can be nil? + // Should we fail loudly? Wait for the httpClient to be ready? + if (!request) { + return nil; + } + return [ArtsyAPI performRequest:request success:success failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) { if (failure) { failure(error); @@ -31,6 +38,11 @@ + (AFHTTPRequestOperation *)deleteAPNTokenForCurrentDeviceWithCompletion:(void ( return nil; } NSURLRequest *request = [ARRouter newDeleteDeviceRequest:token]; + + if (!request) { + completion(); + return nil; + } return [ArtsyAPI performRequest:request success:^ (id _) { completion(); } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) { From 4d8533b008d272d196393c0a3986459aa8ae0b0f Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Fri, 30 May 2025 12:49:12 -0300 Subject: [PATCH 48/60] bring back native module code, wait on hydration --- src/app/store/AuthModel.ts | 9 ++++----- src/app/system/devTools/useMaestroInitialization.ts | 7 +++++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/app/store/AuthModel.ts b/src/app/store/AuthModel.ts index d111cc31b4e..8f202b64cae 100644 --- a/src/app/store/AuthModel.ts +++ b/src/app/store/AuthModel.ts @@ -5,7 +5,7 @@ import AsyncStorage from "@react-native-async-storage/async-storage" import CookieManager from "@react-native-cookies/cookies" import { GoogleSignin, statusCodes } from "@react-native-google-signin/google-signin" import * as Sentry from "@sentry/react-native" -// import { LegacyNativeModules } from "app/NativeModules/LegacyNativeModules" +import { LegacyNativeModules } from "app/NativeModules/LegacyNativeModules" import { clearNavState } from "app/system/navigation/useReloadedDevNavigationState" import { _globalCacheRef } from "app/system/relay/defaultEnvironment" import { @@ -992,10 +992,9 @@ export const getAuthModel = (): AuthModel => ({ SegmentTrackingProvider.identify?.(undefined, { is_temporary_user: 1 }) await Promise.all([ - // TODO: Figure out why this is breaking for Maestro - // Platform.OS === "ios" - // ? await LegacyNativeModules.ArtsyNativeModule.clearUserData() - // : Promise.resolve(), + Platform.OS === "ios" + ? await LegacyNativeModules.ArtsyNativeModule.clearUserData() + : Promise.resolve(), __DEV__ && (await clearNavState()), await signOutGoogle(), LoginManager.logOut(), diff --git a/src/app/system/devTools/useMaestroInitialization.ts b/src/app/system/devTools/useMaestroInitialization.ts index 078b039a1ea..f78838a3111 100644 --- a/src/app/system/devTools/useMaestroInitialization.ts +++ b/src/app/system/devTools/useMaestroInitialization.ts @@ -11,9 +11,12 @@ interface MaestroLaunchArguments { export const useMaestroInitialization = () => { const isLoggedIn = GlobalStore.useAppState((state) => !!state.auth.userAccessToken) + const isHydrated = GlobalStore.useAppState((state) => state.sessionState.isHydrated) useEffect(() => { - if (!ArtsyNativeModule.isBetaOrDev) return + if (!ArtsyNativeModule.isBetaOrDev || !isHydrated) { + return + } const args = LaunchArguments.value() const email = args.email @@ -30,5 +33,5 @@ export const useMaestroInitialization = () => { } else if (shouldSignOut && isLoggedIn) { GlobalStore.actions.auth.signOut() } - }, []) + }, [isHydrated]) } From 981f23c42798bc09dca213149a13ffd4f0f5b54e Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Fri, 30 May 2025 14:17:51 -0300 Subject: [PATCH 49/60] tie e2e to beta ios builds for now --- .circleci/config.yml | 137 +++++++++++++++++++------------------------ 1 file changed, 61 insertions(+), 76 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 39983119cbd..cd9f783b8a3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -570,29 +570,6 @@ workflows: requires: - deploy-nightly-beta - run-e2e-beta-test: - jobs: - - deploy-nightly-beta: - filters: - branches: - only: - - brian/e2e-again - - run-e2e-tests: - requires: - - deploy-nightly-beta - filters: - branches: - only: - - brian/e2e-again - - # run-e2e: - # jobs: - # - run-e2e-tests: - # filters: - # branches: - # only: - # - brian/e2e-again - flag-check: triggers: - schedule: @@ -619,56 +596,64 @@ workflows: ignore: - main - # - check-code: - # context: danger-github-oss - - # - check-and-deploy: - # filters: - # branches: - # only: - # - main - - # - test-js - - # - build-test-js - - # - horizon/block: - # context: horizon - # project_id: 37 - # filters: - # branches: - # only: - # - beta-ios - # - beta-android - - # - build-test-app-ios: - # filters: - # branches: - # ignore: - # - beta-android - # requires: - # - test-js - # - check-code - # - build-test-js - # - horizon/block - - # - build-test-app-android: - # filters: - # branches: - # ignore: - # - beta-ios - # requires: - # - test-js - # - check-code - # - build-test-js - # - horizon/block - - # - update-metaphysics: - # filters: - # branches: - # only: - # - beta-ios - # - beta-android - # requires: - # - build-test-app-ios - # - build-test-app-android + - check-code: + context: danger-github-oss + + - check-and-deploy: + filters: + branches: + only: + - main + + - test-js + + - build-test-js + + - horizon/block: + context: horizon + project_id: 37 + filters: + branches: + only: + - beta-ios + - beta-android + + - build-test-app-ios: + filters: + branches: + ignore: + - beta-android + requires: + - test-js + - check-code + - build-test-js + - horizon/block + + - build-test-app-android: + filters: + branches: + ignore: + - beta-ios + requires: + - test-js + - check-code + - build-test-js + - horizon/block + + - update-metaphysics: + filters: + branches: + only: + - beta-ios + - beta-android + requires: + - build-test-app-ios + - build-test-app-android + + - run-e2e-tests: + filters: + branches: + only: + - beta-ios + requires: + - build-test-app-ios From 7051f2dd7f4134910c006b5b6d5382ee3fb4173a Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Fri, 30 May 2025 16:17:27 -0300 Subject: [PATCH 50/60] fix zip file creation --- fastlane/utility_fastlane.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fastlane/utility_fastlane.rb b/fastlane/utility_fastlane.rb index 2e0480c5930..2c4f3192851 100644 --- a/fastlane/utility_fastlane.rb +++ b/fastlane/utility_fastlane.rb @@ -1,3 +1,5 @@ +require "pathname" + # Utility functions desc "Updates the version string in app.json" @@ -93,8 +95,11 @@ zip_name = "#{app_name}-#{app_version}.zip" zip_path = File.join(archive_root, zip_name) latest_zip_path = File.join(archive_root, "#{app_name}-latest.zip") + app_dir = File.dirname(app_path) + app_folder = File.basename(app_path) + zip_path_absolute = Pathname.new(zip_path).realpath.to_s rescue Pathname.new(zip_path).expand_path.to_s - sh("zip -r #{zip_path} '#{app_path}'") + sh("cd '#{app_dir}' && zip -r '#{zip_path_absolute}' '#{app_folder}'") FileUtils.cp(zip_path, latest_zip_path) # Upload both versioned and "latest" From d35f9ccfb427301e0997d39bfb502a9832d5fdb1 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Fri, 30 May 2025 18:00:42 -0300 Subject: [PATCH 51/60] update version number --- app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.json b/app.json index 414cff43fc8..0e256659271 100644 --- a/app.json +++ b/app.json @@ -1,6 +1,6 @@ { "appName": "eigen", - "version": "8.74.0", + "version": "8.75.0", "isAndroidBeta": false, "slug": "eigen", "expo": { From 2ec1c411ec8cde9eab6005a8a5035966859d1ef0 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Tue, 3 Jun 2025 18:02:50 -0400 Subject: [PATCH 52/60] add active arch flag to speed up sim build --- scripts/ci/build-for-tests-ios | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ci/build-for-tests-ios b/scripts/ci/build-for-tests-ios index d91bf82b204..c004c294d1b 100755 --- a/scripts/ci/build-for-tests-ios +++ b/scripts/ci/build-for-tests-ios @@ -1,6 +1,6 @@ #!/usr/bin/env bash set -euxo pipefail -xcodebuild -workspace "$WORKSPACE" -scheme "$SCHEME" -configuration Debug -sdk iphonesimulator build -destination platform="$DEVICE_HOST_PLAT",OS="$DEVICE_HOST_OS",name="$DEVICE_HOST_NAME" -derivedDataPath "$DERIVED_DATA_PATH" GCC_PREPROCESSOR_DEFINITIONS='$(inherited)' | +xcodebuild -workspace "$WORKSPACE" -scheme "$SCHEME" -configuration Debug -sdk iphonesimulator build -destination platform="$DEVICE_HOST_PLAT",OS="$DEVICE_HOST_OS",name="$DEVICE_HOST_NAME" -derivedDataPath "$DERIVED_DATA_PATH" ONLY_ACTIVE_ARCH=YES GCC_PREPROCESSOR_DEFINITIONS='$(inherited)' | tee ./xcode_build_raw.log | bundle exec xcpretty -c From afee5ec48a1fd305737dd37153b7cb70aaf59f79 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Tue, 3 Jun 2025 18:14:20 -0400 Subject: [PATCH 53/60] upgrade to xcode 16.2 and 18.2 sim --- .circleci/config.yml | 12 ++++++------ ios/ArtsyTests/Supporting_Files/ARTestHelper.m | 4 ++-- scripts/ci/ci-setup-export-vars | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index cd9f783b8a3..0a852d67a67 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -175,7 +175,7 @@ jobs: BUNDLE_PATH: .vendor macos: - xcode: 16.1 + xcode: 16.2 resource_class: macos.m1.medium.gen1 steps: @@ -242,7 +242,7 @@ jobs: BUNDLE_PATH: .vendor macos: - xcode: 16.1 + xcode: 16.2 resource_class: macos.m1.medium.gen1 steps: @@ -263,7 +263,7 @@ jobs: BUNDLE_PATH: .vendor macos: - xcode: 16.1 + xcode: 16.2 resource_class: macos.m1.medium.gen1 steps: @@ -355,7 +355,7 @@ jobs: BUNDLE_PATH: .vendor # path to install gems and use for caching macos: - xcode: 16.1 + xcode: 16.2 resource_class: macos.m1.medium.gen1 steps: @@ -429,7 +429,7 @@ jobs: BUNDLE_PATH: .vendor # path to install gems and use for caching macos: - xcode: 16.1 + xcode: 16.2 resource_class: macos.m1.medium.gen1 steps: @@ -469,7 +469,7 @@ jobs: - install-gems - install-cocoapods - macos/preboot-simulator: - version: "18.1" + version: "18.2" platform: "iOS" device: "iPhone 16 Pro" - build-app-ios diff --git a/ios/ArtsyTests/Supporting_Files/ARTestHelper.m b/ios/ArtsyTests/Supporting_Files/ARTestHelper.m index f6445edc6f4..6be9aa1a068 100644 --- a/ios/ArtsyTests/Supporting_Files/ARTestHelper.m +++ b/ios/ArtsyTests/Supporting_Files/ARTestHelper.m @@ -16,8 +16,8 @@ - (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions: { NSOperatingSystemVersion version = [NSProcessInfo processInfo].operatingSystemVersion; - NSAssert(version.majorVersion == 18 && version.minorVersion == 1, - @"The tests should be run on iOS 18.1, not %ld.%ld", version.majorVersion, version.minorVersion); + NSAssert(version.majorVersion == 18 && version.minorVersion == 2, + @"The tests should be run on iOS 18.2, not %ld.%ld", version.majorVersion, version.minorVersion); CGSize nativeResolution = [UIScreen mainScreen].nativeBounds.size; NSAssert([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone && CGSizeEqualToSize(nativeResolution, CGSizeMake(1206, 2622)), diff --git a/scripts/ci/ci-setup-export-vars b/scripts/ci/ci-setup-export-vars index e6e4bb6766d..602c5ff5f20 100755 --- a/scripts/ci/ci-setup-export-vars +++ b/scripts/ci/ci-setup-export-vars @@ -10,7 +10,7 @@ export LOCAL_BRANCH export WORKSPACE="ios/Artsy.xcworkspace" export SCHEME="Artsy" export DEVICE_HOST_PLAT="iOS Simulator" -export DEVICE_HOST_OS="18.1" +export DEVICE_HOST_OS="18.2" export DEVICE_HOST_NAME="iPhone 16 Pro" export DERIVED_DATA_PATH="derived_data" export CONFIGURATION="Release" From 3ba4a50f12795f9240df47a33e07a05f67e99b2e Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Tue, 3 Jun 2025 18:16:31 -0400 Subject: [PATCH 54/60] upload sim builds to s3 --- scripts/ci/build-for-tests-ios | 2 ++ scripts/ci/upload_sim_app | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100755 scripts/ci/upload_sim_app diff --git a/scripts/ci/build-for-tests-ios b/scripts/ci/build-for-tests-ios index c004c294d1b..ccac9ddc5ff 100755 --- a/scripts/ci/build-for-tests-ios +++ b/scripts/ci/build-for-tests-ios @@ -4,3 +4,5 @@ set -euxo pipefail xcodebuild -workspace "$WORKSPACE" -scheme "$SCHEME" -configuration Debug -sdk iphonesimulator build -destination platform="$DEVICE_HOST_PLAT",OS="$DEVICE_HOST_OS",name="$DEVICE_HOST_NAME" -derivedDataPath "$DERIVED_DATA_PATH" ONLY_ACTIVE_ARCH=YES GCC_PREPROCESSOR_DEFINITIONS='$(inherited)' | tee ./xcode_build_raw.log | bundle exec xcpretty -c + +./scripts/ci/upload_sim_app.sh \ No newline at end of file diff --git a/scripts/ci/upload_sim_app b/scripts/ci/upload_sim_app new file mode 100755 index 00000000000..01c40dc187c --- /dev/null +++ b/scripts/ci/upload_sim_app @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +set -euxo pipefail + +APP_NAME="Artsy" +DERIVED_DATA_PATH="${DERIVED_DATA_PATH:-derived_data}" +S3_DEST="s3://artsy-citadel/eigen/builds/ios/${APP_NAME}-latest.zip" + +# Find the .app bundle +APP_PATH=$(find "$DERIVED_DATA_PATH/Build/Products/Debug-iphonesimulator" -name "${APP_NAME}.app" -type d | head -n1) + +if [ -z "$APP_PATH" ]; then + echo "❌ .app not found!" >&2 + exit 1 +fi + +echo "✅ Found app at: $APP_PATH" + +# Zip the .app bundle +ZIP_NAME="${APP_NAME}-latest.zip" +cd "$(dirname "$APP_PATH")" +zip -r "$ZIP_NAME" "$(basename "$APP_PATH")" + +# Upload to S3 +aws s3 cp "$ZIP_NAME" "$S3_DEST" + +echo "✅ Uploaded $ZIP_NAME to $S3_DEST" From 8a849a6266d0ef507ee0b9d7eba209ccfa458516 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Tue, 3 Jun 2025 18:23:44 -0400 Subject: [PATCH 55/60] make e2e dependent on test app rather than betas --- .circleci/config.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0a852d67a67..ca7dffc0e06 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -564,11 +564,12 @@ workflows: only: - main jobs: + - build-test-app-ios - deploy-nightly-beta - run-nightly-tasks - run-e2e-tests: requires: - - deploy-nightly-beta + - build-test-app-ios flag-check: triggers: From 5cb2371aa2c3556ba437ff7d086b9b77093f329b Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Tue, 3 Jun 2025 18:28:03 -0400 Subject: [PATCH 56/60] clean up --- .circleci/config.yml | 3 --- fastlane/Fastfile | 4 ---- 2 files changed, 7 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ca7dffc0e06..8f42452cf32 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -214,9 +214,6 @@ jobs: - run: name: Install idb command: brew tap facebook/fb && brew install idb-companion - - run: - name: Test maestro install - command: maestro --version - run: name: Clear project dir command: | diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 51e4fedf360..68c4ab6d070 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -102,10 +102,6 @@ lane :ship_beta_ios do |options| dist_version: bundle_version, platform: 'ios' ) - - s3_upload_ios_build( - app_version: bundle_version - ) end deploy_ios_beta(deployment_target: deployment_target) From 4b8960c63bd2287ad6a12df39bfdf1056eac48e3 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Wed, 4 Jun 2025 10:00:36 -0400 Subject: [PATCH 57/60] typo in script --- scripts/ci/build-for-tests-ios | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ci/build-for-tests-ios b/scripts/ci/build-for-tests-ios index ccac9ddc5ff..05a213fa394 100755 --- a/scripts/ci/build-for-tests-ios +++ b/scripts/ci/build-for-tests-ios @@ -5,4 +5,4 @@ xcodebuild -workspace "$WORKSPACE" -scheme "$SCHEME" -configuration Debug -sdk i tee ./xcode_build_raw.log | bundle exec xcpretty -c -./scripts/ci/upload_sim_app.sh \ No newline at end of file +./scripts/ci/upload_sim_app \ No newline at end of file From 06115c8fe261db5512c8b3e6372cd0cb89d7d9a6 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Wed, 4 Jun 2025 13:54:41 -0400 Subject: [PATCH 58/60] pr review: remove hardcoded appId --- e2e/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/config.yml b/e2e/config.yml index 75693b68877..86e2329dfbe 100644 --- a/e2e/config.yml +++ b/e2e/config.yml @@ -1,4 +1,4 @@ -appId: net.artsy.artsy +appId: ${MAESTRO_APP_ID} --- flows: - "flows/*" From 5a489b12d6026bf8b3a4e4b0cf5f5a30729b0742 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Wed, 4 Jun 2025 14:20:35 -0400 Subject: [PATCH 59/60] pr review: move script to utils --- .circleci/config.yml | 2 +- .../utils/install_app_in_booted_sims.sh | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename install_app_in_booted_sims.sh => scripts/utils/install_app_in_booted_sims.sh (100%) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8f42452cf32..7983feb0a0b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -228,7 +228,7 @@ jobs: command: unzip Artsy.zip - run: name: Install app in booted sims - command: ./install_app_in_booted_sims.sh + command: ./scripts/utils/install_app_in_booted_sims.sh - run: name: Run Maestro Tests no_output_timeout: 25m diff --git a/install_app_in_booted_sims.sh b/scripts/utils/install_app_in_booted_sims.sh similarity index 100% rename from install_app_in_booted_sims.sh rename to scripts/utils/install_app_in_booted_sims.sh From e8051afafd5adcab558807651a5f2df2b75461e7 Mon Sep 17 00:00:00 2001 From: brainbicycle Date: Wed, 4 Jun 2025 15:10:51 -0400 Subject: [PATCH 60/60] pr review: move env vars to file --- .circleci/config.yml | 5 ++++- e2e/set_env_vars.sh | 6 ------ package.json | 2 ++ scripts/setup/setup-env-for-maestro | 4 ++++ scripts/setup/update-env-for-maestro | 15 +++++++++++++++ .../utils/run_maestro_shard.sh | 2 +- 6 files changed, 26 insertions(+), 8 deletions(-) delete mode 100755 e2e/set_env_vars.sh create mode 100755 scripts/setup/setup-env-for-maestro create mode 100755 scripts/setup/update-env-for-maestro rename run_maestro_shard.sh => scripts/utils/run_maestro_shard.sh (87%) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7983feb0a0b..c63f99a1b93 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -220,6 +220,9 @@ jobs: rm -rf /Users/distiller/project/* - checkout - setup-awscli + - run: + name: Set up maestro env + command: ./scripts/setup/setup-maestro-env.sh - run: name: Download app zip command: aws s3 cp s3://artsy-citadel/eigen/builds/ios/Artsy-latest.zip ./Artsy.zip @@ -232,7 +235,7 @@ jobs: - run: name: Run Maestro Tests no_output_timeout: 25m - command: ./run_maestro_shard.sh + command: ./scripts/utils/run_maestro_shard.sh deploy-nightly-beta: environment: diff --git a/e2e/set_env_vars.sh b/e2e/set_env_vars.sh deleted file mode 100755 index 69977de4d88..00000000000 --- a/e2e/set_env_vars.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -# TODO: make work for android as well -export MAESTRO_APP_ID=net.artsy.artsy -export MAESTRO_TEST_EMAIL=detox+test@example.com -export MAESTRO_TEST_PASSWORD='$###$someT0ughP4$$' \ No newline at end of file diff --git a/package.json b/package.json index 6a0cdde50b3..14f2c854b06 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,8 @@ "setup:artsy": "./scripts/setup/setup-env-for-artsy", "setup:artsy:update!": "scripts/setup/update-env-for-artsy", "setup:oss": "./scripts/setup/setup-env-for-oss", + "setup:maestro": "./scripts/setup/setup-env-for-maestro", + "setup:maestro:update!": "scripts/setup/update-env-for-maestro", "setup:releases": "./scripts/setup/setup-env-for-artsy && ./scripts/setup/setup-env-for-releases", "setup:releases:update!": "scripts/setup/update-env-for-releases", "start": "concurrently 'yarn relay:watch' 'react-native start'", diff --git a/scripts/setup/setup-env-for-maestro b/scripts/setup/setup-env-for-maestro new file mode 100755 index 00000000000..0c68823b07c --- /dev/null +++ b/scripts/setup/setup-env-for-maestro @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -euxo pipefail + +aws s3 cp s3://artsy-citadel/eigen/.env.maestro .env.maestro diff --git a/scripts/setup/update-env-for-maestro b/scripts/setup/update-env-for-maestro new file mode 100755 index 00000000000..68f5f99ce77 --- /dev/null +++ b/scripts/setup/update-env-for-maestro @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +set -euxo pipefail + + +read -p "Are you sure you want to update the env vars in S3? " -n 1 -r + +if [[ $REPLY =~ ^[Yy]$ ]] +then + aws s3 cp .env.maestro s3://artsy-citadel/eigen/.env.maestro + + RED='\033[0;31m' + RST='\033[0m' + + printf "${RED}Don't forget to update on 1Password and CircleCI too!${RST}\n" +fi diff --git a/run_maestro_shard.sh b/scripts/utils/run_maestro_shard.sh similarity index 87% rename from run_maestro_shard.sh rename to scripts/utils/run_maestro_shard.sh index 802d65e8949..1626927e3f9 100755 --- a/run_maestro_shard.sh +++ b/scripts/utils/run_maestro_shard.sh @@ -6,7 +6,7 @@ EXIT_CODE=0 for TEST_FILE in $TEST_FILES; do echo "Running test: $TEST_FILE" - maestro test "$TEST_FILE" + maestro test "$TEST_FILE" @.env.maestro if [ $? -ne 0 ]; then EXIT_CODE=1 fi