diff --git a/.env.sample b/.env.sample index 5681ce4e2..87ad42779 100644 --- a/.env.sample +++ b/.env.sample @@ -1,15 +1,18 @@ # this is a sample .env file. Copy it to .env, and edit the .env file to match your needs. +# Test binaries ANDROID_APK=/home/yougotthis/Downloads/session-android-universal.apk IOS_APP_PATH_PREFIX=/home/yougotthis/Downloads/Session.app -SDK_MANAGER_FULL_PATH=/home/yougotthis/Android/Sdk/cmdline-tools/latest/bin/sdkmanager -AVD_MANAGER_FULL_PATH=/home/yougotthis/Android/Sdk/cmdline-tools/latest/bin/avdmanager -EMULATOR_FULL_PATH=/home/yougotthis/Android/Sdk/emulator/emulator + +# Environment variables +ANDROID_SDK_ROOT=/home/yougotthis/Android/Sdk ANDROID_SYSTEM_IMAGE="system-images;android-35;google_atd;x86_64" -APPIUM_ADB_FULL_PATH=/home/yougotthis/Android/sdk/platform-tools/adb -PRINT_TEST_LOGS=true -PRINT_ONGOING_TEST_LOGS = 1 + +# Playwright and reporting +PRINT_ONGOING_TEST_LOGS=1 PRINT_FAILED_TEST_LOGS=1 PLAYWRIGHT_RETRIES_COUNT=0 PLAYWRIGHT_REPEAT_COUNT=0 -PLAYWRIGHT_WORKERS_COUNT=1 \ No newline at end of file +PLAYWRIGHT_WORKERS_COUNT=1 +CI=0 +ALLURE_ENABLED='false' \ No newline at end of file diff --git a/.github/workflows/android-regression.yml b/.github/workflows/android-regression.yml index ac5d80671..464ddbdd0 100644 --- a/.github/workflows/android-regression.yml +++ b/.github/workflows/android-regression.yml @@ -4,6 +4,14 @@ run-name: '${{ inputs.RISK }} regressions on ${{ github.head_ref || github.ref } on: workflow_dispatch: inputs: + RUNNER: + description: 'Which runner to use' + required: true + type: choice + options: + - 'linux' + - 'mac' + default: 'linux' APK_URL: description: 'apk url to test (.tar.xz)' required: true @@ -55,9 +63,13 @@ on: jobs: android-regression: - runs-on: [self-hosted, linux, X64, qa-android] + runs-on: ${{ github.event.inputs.RUNNER == 'mac' && fromJSON('["self-hosted", "macOS"]') || fromJSON('["self-hosted", "linux", "X64", "qa-android"]') }} env: PLATFORM: 'android' + EMULATOR_COUNT: ${{ github.event.inputs.RUNNER == 'mac' && '6' || '4' }} # macOS runner can support 6 emulators, linux runner only 4 + WORKERS_1_DEVICE: ${{ github.event.inputs.RUNNER == 'mac' && '6' || '4' }} # 6 or 4 workers, 1 device each + WORKERS_2_DEVICE: ${{ github.event.inputs.RUNNER == 'mac' && '3' || '2' }} # 3 or 2 workers, 2 devices each + WORKERS_3_DEVICE: ${{ github.event.inputs.RUNNER == 'mac' && '2' || '1' }} # 2 or 1 worker(s), 3 devices each APK_URL: ${{ github.event.inputs.APK_URL }} BUILD_NUMBER: ${{ github.event.inputs.BUILD_NUMBER }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -65,8 +77,6 @@ jobs: ALLURE_ENABLED: ${{ github.event.inputs.ALLURE_ENABLED}} IOS_APP_PATH_PREFIX: '' ANDROID_APK: './extracted/session-android.apk' - APPIUM_ADB_FULL_PATH: '/opt/android/platform-tools/adb' - ANDROID_SDK_ROOT: '/opt/android' PLAYWRIGHT_RETRIES_COUNT: ${{ github.event.inputs.PLAYWRIGHT_RETRIES_COUNT }} _TESTING: 1 # Always hide webdriver logs (@appium/support/ flag) PRINT_FAILED_TEST_LOGS: ${{ github.event.inputs.LOG_LEVEL != 'minimal' && '1' || '0' }} # Show stdout/stderr if test fails (@session-foundation/playwright-reporter/ flag) @@ -77,6 +87,40 @@ jobs: with: lfs: true + # This is necessary because the macOS runner was not always pulling the lfs files despite checkout with lfs: true + # Check if LFS files were actually pulled + - name: Verify LFS files + run: | + echo "Ensuring all LFS screenshot files are downloaded..." + git lfs pull --include="run/screenshots/**/*.png" + + echo "=== Verifying screenshot files ===" + corrupted_files=0 + total_files=0 + + for file in run/screenshots/**/*.png; do + if [[ -f "$file" ]]; then # Make sure file exists (in case glob doesn't match anything) + ((total_files++)) + if file "$file" | grep -q "PNG image"; then + echo "โœ… $file" + else + echo "โš ๏ธ WARNING: $file is not a PNG image - related tests may fail" + # Show what it actually is for debugging + echo " File type: $(file "$file")" + ((corrupted_files++)) + fi + fi + done + + echo "๐Ÿ“Š Screenshot verification: $((total_files - corrupted_files))/$total_files files valid" + + if [ $corrupted_files -gt 0 ]; then + echo "โš ๏ธ Found $corrupted_files corrupted screenshot files" + echo "๐Ÿ“ Tests using these files will be skipped or may fail" + else + echo "โœ… All screenshot files are valid PNG images" + fi + - name: Fetch result history from gh-pages uses: ./github/actions/fetch-allure-history if: ${{ env.ALLURE_ENABLED == 'true' }} @@ -95,7 +139,7 @@ jobs: - name: Download APK & extract it run: | pwd - wget -q -O session-android.apk.tar.xz ${{ github.event.inputs.APK_URL }} + curl -L -o session-android.apk.tar.xz ${{ github.event.inputs.APK_URL }} tar xf session-android.apk.tar.xz mv session-android-*universal extracted @@ -118,72 +162,79 @@ jobs: continue-on-error: true # just so we don't fail if adb wasn't already running run: | source ./scripts/ci.sh + echo "ANDROID_SDK_ROOT=${ANDROID_SDK_ROOT}" >> $GITHUB_ENV adb kill-server; adb start-server; - - name: Start emulators from snapshot + - name: Start emulators shell: bash - run: | + run: | # macOS can handle cold boot, linux cannot source ./scripts/ci.sh - start_with_snapshots + if [[ "${{ github.event.inputs.RUNNER }}" == "mac" ]]; then + start_for_snapshots + else + start_with_snapshots + fi wait_for_emulators - - name: List tests part of this run uses: ./github/actions/list-tests with: PLATFORM: ${{ env.PLATFORM }} RISK: ${{ github.event.inputs.RISK }} - - name: Run the 1-devices tests โ€‹โ€‹with 4 workers - continue-on-error: true - id: devices-1-test-run - env: - PLAYWRIGHT_WORKERS_COUNT: 4 - DEVICES_PER_TEST_COUNT: 1 + - name: Run 1-device tests + id: test-1-device + uses: ./github/actions/run-tests + with: + PLATFORM: ${{ env.PLATFORM }} + RISK: ${{ github.event.inputs.RISK }} + WORKERS_COUNT: ${{ env.WORKERS_1_DEVICE }} + DEVICES_PER_TEST: 1 _TESTING: ${{ env._TESTING }} PRINT_FAILED_TEST_LOGS: ${{ env.PRINT_FAILED_TEST_LOGS }} PRINT_ONGOING_TEST_LOGS: ${{ env.PRINT_ONGOING_TEST_LOGS }} - run: | - pwd - npx playwright test --grep "(?=.*@${PLATFORM})(?=.*@${DEVICES_PER_TEST_COUNT}-devices)(?=.*@${{ github.event.inputs.RISK }})" #Note: this has to be double quotes - - name: Upload results of this run + - name: Upload 1-device test results uses: ./github/actions/upload-test-results with: PLATFORM: ${{ env.PLATFORM }} - UPLOAD_IDENTIFIER: 'devices-1-test-run' - - - name: Run the 2-devices tests โ€‹โ€‹with 2 workers - continue-on-error: true - id: devices-2-test-run - env: - PLAYWRIGHT_WORKERS_COUNT: 2 - DEVICES_PER_TEST_COUNT: 2 + UPLOAD_IDENTIFIER: devices-1-test-run + + - name: Run 2-device tests + id: test-2-device + uses: ./github/actions/run-tests + with: + PLATFORM: ${{ env.PLATFORM }} + RISK: ${{ github.event.inputs.RISK }} + WORKERS_COUNT: ${{ env.WORKERS_2_DEVICE }} + DEVICES_PER_TEST: 2 _TESTING: ${{ env._TESTING }} PRINT_FAILED_TEST_LOGS: ${{ env.PRINT_FAILED_TEST_LOGS }} PRINT_ONGOING_TEST_LOGS: ${{ env.PRINT_ONGOING_TEST_LOGS }} - run: | - pwd - npx playwright test --grep "(?=.*@${PLATFORM})(?=.*@${DEVICES_PER_TEST_COUNT}-devices)(?=.*@${{ github.event.inputs.RISK }})" #Note: this has to be double quotes - - name: Upload results of this run + - name: Upload 2-device test results uses: ./github/actions/upload-test-results with: PLATFORM: ${{ env.PLATFORM }} - UPLOAD_IDENTIFIER: 'devices-2-test-run' - - - name: Run the other tests with 1 worker - continue-on-error: true - id: other-devices-test-run - env: - PLAYWRIGHT_WORKERS_COUNT: 1 - DEVICES_PER_TEST_COUNT: 4 + UPLOAD_IDENTIFIER: devices-2-test-run + + - name: Run 3-device tests + id: test-3-device + uses: ./github/actions/run-tests + with: + PLATFORM: ${{ env.PLATFORM }} + RISK: ${{ github.event.inputs.RISK }} + WORKERS_COUNT: ${{ env.WORKERS_3_DEVICE }} + DEVICES_PER_TEST: '3' _TESTING: ${{ env._TESTING }} PRINT_FAILED_TEST_LOGS: ${{ env.PRINT_FAILED_TEST_LOGS }} PRINT_ONGOING_TEST_LOGS: ${{ env.PRINT_ONGOING_TEST_LOGS }} - run: | - pwd - npx playwright test --grep "(?=.*@${PLATFORM})(?=.*@${{ github.event.inputs.RISK }})" --grep-invert "@1-devices|@2-devices" #Note: this has to be double quotes + + - name: Upload 3-device test results + uses: ./github/actions/upload-test-results + with: + PLATFORM: ${{ env.PLATFORM }} + UPLOAD_IDENTIFIER: devices-3-test-run - name: Generate and publish test report uses: ./github/actions/generate-publish-test-report @@ -197,12 +248,6 @@ jobs: GITHUB_RUN_NUMBER: ${{ github.run_number }} GITHUB_RUN_ATTEMPT: ${{ github.run_attempt }} - - name: Upload results of this run - uses: ./github/actions/upload-test-results - with: - PLATFORM: ${{ env.PLATFORM }} - UPLOAD_IDENTIFIER: 'devices-other-test-run' - - name: Upload csv of this whole run uses: ./github/actions/upload-csv-test-results if: always() diff --git a/.github/workflows/ios-regression.yml b/.github/workflows/ios-regression.yml index e0f415a1e..1963e1fd9 100644 --- a/.github/workflows/ios-regression.yml +++ b/.github/workflows/ios-regression.yml @@ -51,7 +51,8 @@ on: - '1' - '2' - '3' - default: '3' + - '4' # 4 is the max for our self hosted runner at the moment + default: '4' LOG_LEVEL: description: 'Test logging verbosity (WARNING: anything other than minimal mode may crash GitHub Actions on large test runs)' @@ -81,7 +82,7 @@ jobs: _TESTING: 1 # Always hide webdriver logs (@appium/support/ flag) PRINT_FAILED_TEST_LOGS: ${{ github.event.inputs.LOG_LEVEL != 'minimal' && '1' || '0' }} # Show stdout/stderr if test fails (@session-foundation/playwright-reporter/ flag) PRINT_ONGOING_TEST_LOGS: ${{ github.event.inputs.LOG_LEVEL == 'verbose' && '1' || '0' }} # Show everything as it happens (@session-foundation/playwright-reporter/ flag) - PLAYWRIGHT_WORKERS_COUNT: 3 # for iOS, this is the max we can have on our self-hosted runner + PLAYWRIGHT_WORKERS_COUNT: ${{ github.event.inputs.PLAYWRIGHT_WORKERS_COUNT }} SDK_MANAGER_FULL_PATH: '' AVD_MANAGER_FULL_PATH: '' ANDROID_SYSTEM_IMAGE: '' diff --git a/.nvmrc b/.nvmrc index 55bffd620..6263619f7 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -18.15.0 +20.18.2 \ No newline at end of file diff --git a/README.md b/README.md index 2328031d8..c3bd77a1b 100644 --- a/README.md +++ b/README.md @@ -1,93 +1,118 @@ -# Automation testing for Session - -This repository holds the code to do integration tests with Appium and Session on iOS and Android. - -# Setup - -## Android SDK & Emulators - -First, you need to download android studio at https://developer.android.com/studio. - -Once installed, run it, open the SDK Manager and install the latest SDK tools. - -Once this is done, open up the AVD Manager, click on "Create Device" -> "Pixel 6" -> Next -> Select the System Image you want (I did my tests with **UpsideDownCake**), install it, select it, "Next" and "Finish". - -Then, create a second emulator following the exact same steps (the tests need 2 different emulators to run). - -Once done, you should be able to start each emulators and have them running at the same time. They will need to be running for the tests to work, because Appium won't start them. - -## Environment variables needed - -Before you can start the tests, you need to setup some environment variables. See the file .env.sample for an example. - -#### ANDROID_SDK_ROOT - -`ANDROID_SDK_ROOT` should point to the folder containing the sdks, so the folder containing folders like `platform-tools`, `system-images`, etc... -`export ANDROID_SDK_ROOT=~/Android/Sdk` - -#### APPIUM_ANDROID_BINARIES_ROOT - -`APPIUM_ANDROID_BINARIES_ROOT` should point to the file containing the apks to install for testing (such as `session-1.18.2-x86.apk`) -`export APPIUM_ANDROID_BINARIES_ROOT=~/appium-binaries` - -#### APPIUM_ADB_FULL_PATH - -`APPIUM_ADB_FULL_PATH` should point to the binary of adb inside the ANDROID_SDK folder -`export APPIUM_ADB_FULL_PATH=~/Android/Sdk/platform-tools/adb` - -### Multiple adb binaries - -Having multiple adb on your system will make tests unreliable, because the server will be restarted by Appium. - -On linux, if running `which adb` does not point to the `adb` binary in the `ANDROID_SDK_ROOT` you will have issues. - -You can get rid of adb on linux by running - +# Automation Testing for Session + +Integration tests for Session app on iOS and Android using Playwright and Appium. + +## Quick Start + +1. **Install dependencies:** + ```bash + nvm use + npm install -g yarn + yarn install --immutable + ``` + +2. **Install Git LFS:** + ```bash + # macOS + brew install git-lfs + + # Linux + sudo apt install git-lfs + + # Then + git lfs install + git lfs pull # Ensure all LFS files are downloaded + ``` +3. **Setup environment:** + ```bash + cp .env.sample .env + # Edit .env with your specific paths - see Environment Configuration below + ``` +4. **Run tests locally:** + ```bash + yarn start-server # Starts Appium server + yarn test # Run all tests + yarn test-android # Android tests only + yarn test-ios # iOS tests only + yarn test-one 'Test name' # Run specific test (both platforms) + yarn test-one 'Test name @android' # Run specific test on one platform + ``` + +## Local Development + +Note: The tests use devices with specific resolutions for visual regression testing - ensure you have these available (see below). + +### Android + +Prerequisites: Android Studio installed with SDK tools available +1. Create 3x Pixel 6 emulators via AVD Manager (minimum 3 emulators - tests require up to 3 devices simultaneously) + - Recommended system image is Android API 34 with Google Play services +2. Download Session binaries from [the build repository](https://oxen.rocks) + - Choose the appropriate binary based on your network access: + - QA: Works on general networks + - AutomaticQA: Requires local devnet access +3. Set environment variable: + ```bash + # In your .env file + ANDROID_APK=/path/to/session-android.apk + ``` +4. Start emulators manually - they need to be running before tests start (Appium won't launch them automatically) + ```bash + emulator @ + ``` + +### iOS +Prerequisites: Xcode installed + +1. Create iOS simulators with preloaded media attachments: + ```bash + # Local development (create 3 simulators to be able to run all tests) + yarn create-simulators 3 + # Or specify custom count + yarn create-simulators + ``` +2. Download Session binaries from the [the build repository](https://oxen.rocks) +3. Extract .app file and copy Session.app to an easily accessible location +4. Set environment variable: + + ```bash + # In your .env file + IOS_APP_PATH_PREFIX=/path/to/Session.app + ``` + +### Environment Configuration + +Copy `.env.sample` to `.env` and configure the following: + +**Required paths:** +```bash +ANDROID_SDK_ROOT=/path/to/Android/Sdk # SDK tools auto-discovered from here +ANDROID_APK=/path/to/session-android.apk # Android APK for testing +IOS_APP_PATH_PREFIX=/path/to/Session.app # iOS app for testing ``` -sudo apt remove adb -sudo apt remove android-tools-adb -``` - -`which adb` should not return anything. - -Somehow, Appium asks for the sdk tools but do not force the adb binary to come from the sdk tools folder. Making sure that there is no adb in your path should solve this. - -## Running tests on iOS Emulators - -First you need to get correct branch of Session that you want to test from Github. See [(https://github.com/session-foundation/session-ios/releases/)] and download the latest **ipa** under **Assets** - -Then to access the **.app** file that Appium needs for testing you need to build in Xcode and then find .app in your **Derived Data** folder for Xcode. -For Mac users this file will exist in: - -Macintosh HD > Username > Library > Developer > Xcode > Derived Data > (Then there will be a version of Session with a very long line of letters) > Build > Products > App store-iphonesimulator > Session.app - -Then Copy and Paste then app file onto Desktop (or anywhere you can access easily) then each time you build, navigate back to the file in Derived Data and copy and paste back to Desktop. -Then set the path to Session.app in your ios capabilities file. - -## Appium & tests setup - -First, install nvm for your system (https://github.com/nvm-sh/nvm). -For windows, head here: https://github.com/coreybutler/nvm-windows -For Mac, https://github.com/nvm-sh/nvm - -``` -nvm install #install node version from the .nvmrc file, currently v16.13.0 -nvm use # use that same node version, currently v16.13.0 -npm install -g yarn -yarn install --frozen # to install packages referenced from yarn.lock +**Test configuration:** +```bash +_TESTING=1 # Skip printing appium/wdio logs +PLAYWRIGHT_RETRIES_COUNT=0 # Test retry attempts +PLAYWRIGHT_REPEAT_COUNT=0 # Successful test repeat count +PLAYWRIGHT_WORKERS_COUNT=1 # Parallel test workers +CI=0 # Set to 1 to simulate CI (mostly for Allure reporting) +ALLURE_ENABLED='false' # Set to 'true' to generate Allure reports (in conjunction with CI=1) ``` -Then, choose an option: +### Multiple ADB Binaries Warning +Having multiple adb installations can cause test instability. On Linux, ensure only the SDK version is available: + +```bash +sudo apt remove adb android-tools-adb +which adb # Should return nothing ``` -yarn tsc # Build typescript files -yarn run test # Run all the tests -Platform specific -yarn run test-android # To run just Android tests -yarn run test-ios # To run just iOS tests +## Test Organization -yarn run test-one 'Name of test' # To run one test (on both platforms) -yarn run test-one 'Name of test android/ios' # To run one test on either platform -``` +Tests are tagged with device requirements and risk levels: +- `@N-devices` - N-device tests (N = 1 || 2 || 3) +- `@high-risk`, `@medium-risk`, `@low-risk` - Risk-based test categorization +- `@android`, `@ios` - Platform-specific tests \ No newline at end of file diff --git a/github/actions/run-tests/action.yml b/github/actions/run-tests/action.yml new file mode 100644 index 000000000..f4ad5e868 --- /dev/null +++ b/github/actions/run-tests/action.yml @@ -0,0 +1,41 @@ +name: 'Run Android Tests' +description: 'Run Android tests with specified configuration' + +inputs: + PLATFORM: + description: 'Platform to test (android/ios)' + required: true + RISK: + description: 'Risk level to test' + required: true + WORKERS_COUNT: + description: 'Number of Playwright workers' + required: true + DEVICES_PER_TEST: + description: 'Number of devices per test' + required: true + +runs: + using: 'composite' + steps: + - name: Run ${{ inputs.DEVICES_PER_TEST }}-device tests + id: run-tests + shell: bash + env: + PLAYWRIGHT_WORKERS_COUNT: ${{ inputs.WORKERS_COUNT }} + DEVICES_PER_TEST_COUNT: ${{ inputs.DEVICES_PER_TEST }} + _TESTING: ${{ env._TESTING }} + PRINT_FAILED_TEST_LOGS: ${{ env.PRINT_FAILED_TEST_LOGS }} + PRINT_ONGOING_TEST_LOGS: ${{ env.PRINT_ONGOING_TEST_LOGS }} + run: | + echo "Running ${{ inputs.DEVICES_PER_TEST }} tests with ${{ inputs.WORKERS_COUNT }} workers" + + grep="(?=.*@${{ inputs.PLATFORM }})(?=.*@${{ inputs.DEVICES_PER_TEST }}-devices)" + [[ "${{ inputs.RISK }}" != "" ]] && grep="${grep}(?=.*@${{ inputs.RISK }})" + + npx playwright test --grep "$grep" + +outputs: + test-result: + description: 'Test result (success/failure)' + value: ${{ steps.run-tests.outcome }} diff --git a/run/test/specs/group_tests_add_contact.spec.ts b/run/test/specs/group_tests_add_contact.spec.ts index 1981a6331..04a4d85be 100644 --- a/run/test/specs/group_tests_add_contact.spec.ts +++ b/run/test/specs/group_tests_add_contact.spec.ts @@ -8,7 +8,7 @@ import { ConversationSettings } from './locators/conversation'; import { Contact } from './locators/global'; import { InviteContactConfirm, ManageMembersMenuItem } from './locators/groups'; import { ConversationItem } from './locators/home'; -import { open_Alice1_Bob1_Charlie1_Unknown1 } from './state_builder'; +import { open_Alice1_Bob1_friends_group_Unknown1 } from './state_builder'; import { sleepFor } from './utils'; import { newUser } from './utils/create_account'; import { newContact } from './utils/create_contact'; @@ -18,22 +18,22 @@ bothPlatformsIt({ title: 'Add contact to group', risk: 'high', testCb: addContactToGroup, - countOfDevicesNeeded: 4, + countOfDevicesNeeded: 3, }); async function addContactToGroup(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Group to test adding contact'; const { - devices: { alice1, bob1, charlie1, unknown1 }, + devices: { alice1, bob1, unknown1 }, prebuilt: { alice, group }, - } = await open_Alice1_Bob1_Charlie1_Unknown1({ + } = await open_Alice1_Bob1_friends_group_Unknown1({ platform, groupName: testGroupName, focusGroupConvo: true, testInfo: testInfo, }); - const userD = await newUser(unknown1, USERNAME.DRACULA); + const userC = await newUser(unknown1, USERNAME.CHARLIE); await alice1.navigateBack(); - await newContact(platform, alice1, alice, unknown1, userD); + await newContact(platform, alice1, alice, unknown1, userC); // Exit to conversation list await alice1.navigateBack(); // Select group conversation in list @@ -49,7 +49,7 @@ async function addContactToGroup(platform: SupportedPlatformsType, testInfo: Tes // Select new user await alice1.clickOnElementAll({ ...new Contact(alice1).build(), - text: USERNAME.DRACULA, + text: USERNAME.CHARLIE, }); await alice1.clickOnElementAll(new InviteContactConfirm(alice1)); // Leave Manage Members @@ -58,9 +58,9 @@ async function addContactToGroup(platform: SupportedPlatformsType, testInfo: Tes await alice1.navigateBack(); // Check control messages await Promise.all( - [alice1, bob1, charlie1].map(device => + [alice1, bob1].map(device => device.waitForControlMessageToBePresent( - englishStrippedStr('groupMemberNew').withArgs({ name: USERNAME.DRACULA }).toString() + englishStrippedStr('groupMemberNew').withArgs({ name: USERNAME.CHARLIE }).toString() ) ) ); @@ -70,5 +70,5 @@ async function addContactToGroup(platform: SupportedPlatformsType, testInfo: Tes await unknown1.onAndroid().navigateBack(); await unknown1.clickOnElementAll(new ConversationItem(unknown1, group.groupName)); // Check for control message on device 4 await unknown1.waitForControlMessageToBePresent(englishStrippedStr('groupInviteYou').toString()); - await closeApp(alice1, bob1, charlie1, unknown1); + await closeApp(alice1, bob1, unknown1); } diff --git a/run/test/specs/linked_device_create_group.spec.ts b/run/test/specs/linked_device_create_group.spec.ts index 40899c26d..314ea0664 100644 --- a/run/test/specs/linked_device_create_group.spec.ts +++ b/run/test/specs/linked_device_create_group.spec.ts @@ -1,131 +1,68 @@ import type { TestInfo } from '@playwright/test'; import { englishStrippedStr } from '../../localizer/englishStrippedStr'; -import { bothPlatformsItSeparate } from '../../types/sessionIt'; -import { USERNAME } from '../../types/testing'; +import { bothPlatformsIt } from '../../types/sessionIt'; import { ConversationHeaderName, ConversationSettings } from './locators/conversation'; import { EditGroupNameInput, SaveGroupNameChangeButton, UpdateGroupInformation, } from './locators/groups'; -import { ConversationItem } from './locators/home'; +import { open_Alice2_Bob1_friends_group } from './state_builder'; import { sleepFor } from './utils'; -import { newUser } from './utils/create_account'; -import { createGroup } from './utils/create_group'; -import { linkedDevice } from './utils/link_device'; -import { closeApp, openAppFourDevices, SupportedPlatformsType } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; -bothPlatformsItSeparate({ - title: 'Create group and change name syncs', +bothPlatformsIt({ + title: 'Group name change syncs', risk: 'high', - countOfDevicesNeeded: 4, - ios: { - testCb: linkedGroupiOS, - }, - android: { - testCb: linkedGroupAndroid, - }, + countOfDevicesNeeded: 3, + testCb: linkedGroup, }); -async function linkedGroupiOS(platform: SupportedPlatformsType, testInfo: TestInfo) { - const { device1, device2, device3, device4 } = await openAppFourDevices(platform, testInfo); - const alice = await linkedDevice(device1, device2, USERNAME.ALICE); - const [bob, charlie] = await Promise.all([ - newUser(device3, USERNAME.BOB), - newUser(device4, USERNAME.CHARLIE), - ]); +async function linkedGroup(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Linked device group'; const newGroupName = 'New group name'; - // Note we keep this createGroup here as we want it to **indeed** use the UI to create the group - await createGroup(platform, device1, alice, device3, bob, device4, charlie, testGroupName); - // Test that group has loaded on linked device - await device2.clickOnElementAll(new ConversationItem(device2, testGroupName)); - // Change group name in device 1 - // Click on settings/more info - await device1.clickOnElementAll(new ConversationSettings(device1)); + const { + devices: { alice1, alice2, bob1 }, + } = await open_Alice2_Bob1_friends_group({ + platform, + groupName: testGroupName, + focusGroupConvo: true, + testInfo: testInfo, + }); + await alice1.clickOnElementAll(new ConversationSettings(alice1)); // Edit group await sleepFor(100); // click on group name to change it - await device1.clickOnElementAll(new UpdateGroupInformation(device1, testGroupName)); + await alice1.clickOnElementAll(new UpdateGroupInformation(alice1, testGroupName)); // Check new dialog - await device1.checkModalStrings( + await alice1.checkModalStrings( englishStrippedStr('updateGroupInformation').toString(), englishStrippedStr('updateGroupInformationDescription').toString() ); // Delete old name first - await device1.deleteText(new EditGroupNameInput(device1)); + await alice1.deleteText(new EditGroupNameInput(alice1)); // Type in new group name - await device1.inputText(newGroupName, new EditGroupNameInput(device1)); + await alice1.inputText(newGroupName, new EditGroupNameInput(alice1)); // Save changes - await device1.clickOnElementAll(new SaveGroupNameChangeButton(device1)); + await alice1.clickOnElementAll(new SaveGroupNameChangeButton(alice1)); // Go back to conversation - await device1.navigateBack(); + await alice1.navigateBack(); // Check control message for changed name const groupNameNew = englishStrippedStr('groupNameNew') .withArgs({ group_name: newGroupName }) .toString(); // Control message should be "Group name is now {group_name}." - await device1.waitForControlMessageToBePresent(groupNameNew); - // Wait 5 seconds for name to update - await sleepFor(5000); + await alice1.waitForControlMessageToBePresent(groupNameNew); // Check linked device for name change (conversation header name) - await device2.waitForTextElementToBePresent(new ConversationHeaderName(device2, newGroupName)); - await Promise.all([ - device2.waitForControlMessageToBePresent(groupNameNew), - device3.waitForControlMessageToBePresent(groupNameNew), - device4.waitForControlMessageToBePresent(groupNameNew), - ]); - await closeApp(device1, device2, device3, device4); -} - -async function linkedGroupAndroid(platform: SupportedPlatformsType, testInfo: TestInfo) { - const testGroupName = 'Test group'; - const newGroupName = 'Changed group name'; - const { device1, device2, device3, device4 } = await openAppFourDevices(platform, testInfo); - // Create users A, B and C - const alice = await linkedDevice(device1, device2, USERNAME.ALICE); - const [bob, charlie] = await Promise.all([ - newUser(device3, USERNAME.BOB), - newUser(device4, USERNAME.CHARLIE), - ]); - // Create group - // Note we keep this createGroup here as we want it to **indeed** use the UI to create the group - await createGroup(platform, device1, alice, device3, bob, device4, charlie, testGroupName); - // Test that group has loaded on linked device - await device2.clickOnElementAll(new ConversationItem(device2, testGroupName)); - // Click on settings or three dots - await device1.clickOnElementAll(new ConversationSettings(device1)); - // Click on Edit group option - await sleepFor(1000); - await device1.clickOnElementAll(new UpdateGroupInformation(device1)); - // Click on current group name - await device1.clickOnElementAll(new EditGroupNameInput(device1)); - // Remove current group name - await device1.deleteText(new EditGroupNameInput(device1)); - // Enter new group name (same test tag for both) - await device1.clickOnElementAll(new EditGroupNameInput(device1)); - await device1.inputText(newGroupName, new EditGroupNameInput(device1)); - // Click done/apply - await device1.clickOnElementAll(new SaveGroupNameChangeButton(device1)); - await device1.navigateBack(); - // Check control message for changed name - const groupNameNew = englishStrippedStr('groupNameNew') - .withArgs({ group_name: newGroupName }) - .toString(); - // Config message is "Group name is now {group_name}" - await device1.waitForControlMessageToBePresent(groupNameNew); - // Check linked device for name change (conversation header name) - await device2.waitForTextElementToBePresent(new ConversationHeaderName(device2, newGroupName)); - await Promise.all([ - device2.waitForControlMessageToBePresent(groupNameNew), - device3.waitForControlMessageToBePresent(groupNameNew), - device4.waitForControlMessageToBePresent(groupNameNew), - ]); - await closeApp(device1, device2, device3, device4); + await alice2.waitForTextElementToBePresent(new ConversationHeaderName(alice2, newGroupName)); + await Promise.all( + [alice1, alice2, bob1].map(device => + device.waitForTextElementToBePresent(new ConversationHeaderName(device, newGroupName)) + ) + ); + await Promise.all( + [alice2, bob1].map(device => device.waitForControlMessageToBePresent(groupNameNew)) + ); + await closeApp(alice1, alice2, bob1); } - -// TODO -// Remove user -// Add user -// Disappearing messages diff --git a/run/test/specs/linked_device_restore_group.spec.ts b/run/test/specs/linked_device_restore_group.spec.ts index e90c6e485..9343805a3 100644 --- a/run/test/specs/linked_device_restore_group.spec.ts +++ b/run/test/specs/linked_device_restore_group.spec.ts @@ -1,50 +1,56 @@ import type { TestInfo } from '@playwright/test'; import { bothPlatformsIt } from '../../types/sessionIt'; -import { USERNAME } from '../../types/testing'; import { ConversationHeaderName, MessageBody } from './locators/conversation'; import { ConversationItem } from './locators/home'; -import { newUser } from './utils/create_account'; -import { createGroup } from './utils/create_group'; -import { closeApp, openAppFourDevices, SupportedPlatformsType } from './utils/open_app'; +import { open_Alice1_Bob1_friends_group_Unknown1 } from './state_builder'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; import { restoreAccount } from './utils/restore_account'; bothPlatformsIt({ title: 'Restore group', risk: 'high', testCb: restoreGroup, - countOfDevicesNeeded: 4, + countOfDevicesNeeded: 3, }); async function restoreGroup(platform: SupportedPlatformsType, testInfo: TestInfo) { - const testGroupName = 'Restore group'; - const { device1, device2, device3, device4 } = await openAppFourDevices(platform, testInfo); - const [alice, bob, charlie] = await Promise.all([ - newUser(device1, USERNAME.ALICE), - newUser(device2, USERNAME.BOB), - newUser(device3, USERNAME.CHARLIE), - ]); - await createGroup(platform, device1, alice, device2, bob, device3, charlie, testGroupName); - - const aliceMessage = `${USERNAME.ALICE} to ${testGroupName}`; - const bobMessage = `${USERNAME.BOB} to ${testGroupName}`; - const charlieMessage = `${USERNAME.CHARLIE} to ${testGroupName}`; - await restoreAccount(device4, alice); + const testGroupName = 'Group to test adding contact'; + const aliceMessage = 'Hello this is alice'; + const bobMessage = 'Hello this is bob'; + const { + devices: { alice1, bob1, unknown1 }, + prebuilt, + } = await open_Alice1_Bob1_friends_group_Unknown1({ + platform, + groupName: testGroupName, + focusGroupConvo: true, + testInfo: testInfo, + }); + const alice = { + userName: prebuilt.alice.userName, + accountID: prebuilt.alice.sessionId, + recoveryPhrase: prebuilt.alice.seedPhrase, + }; + await alice1.sendMessage(aliceMessage); + await bob1.sendMessage(bobMessage); + unknown1.setDeviceIdentity('alice2'); + await restoreAccount(unknown1, alice); // Check that group has loaded on linked device - await device4.clickOnElementAll(new ConversationItem(device4, testGroupName)); + await unknown1.clickOnElementAll(new ConversationItem(unknown1, testGroupName)); // Check the group name has loaded - await device4.waitForTextElementToBePresent(new ConversationHeaderName(device4, testGroupName)); + await unknown1.waitForTextElementToBePresent(new ConversationHeaderName(unknown1, testGroupName)); // Check all messages are present await Promise.all( - [aliceMessage, bobMessage, charlieMessage].map(message => - device4.waitForTextElementToBePresent(new MessageBody(device4, message)) + [aliceMessage, bobMessage].map(message => + unknown1.waitForTextElementToBePresent(new MessageBody(unknown1, message)) ) ); const testMessage2 = 'Checking that message input is working'; - await device4.sendMessage(testMessage2); + await unknown1.sendMessage(testMessage2); await Promise.all( - [device1, device2, device3].map(device => + [alice1, bob1, unknown1].map(device => device.waitForTextElementToBePresent(new MessageBody(device, testMessage2)) ) ); - await closeApp(device1, device2, device3, device4); + await closeApp(alice1, bob1, unknown1, unknown1); } diff --git a/run/test/specs/linked_group_leave.spec.ts b/run/test/specs/linked_group_leave.spec.ts index 19a385504..8db664d93 100644 --- a/run/test/specs/linked_group_leave.spec.ts +++ b/run/test/specs/linked_group_leave.spec.ts @@ -2,53 +2,46 @@ import type { TestInfo } from '@playwright/test'; import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; -import { USERNAME } from '../../types/testing'; import { ConversationSettings } from './locators/conversation'; import { LeaveGroupConfirm, LeaveGroupMenuItem } from './locators/groups'; +import { ConversationItem } from './locators/home'; +import { open_Alice2_Bob1_friends_group } from './state_builder'; import { sleepFor } from './utils'; -import { newUser } from './utils/create_account'; -import { createGroup } from './utils/create_group'; -import { linkedDevice } from './utils/link_device'; -import { closeApp, openAppFourDevices, SupportedPlatformsType } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Leave group linked device', risk: 'high', testCb: leaveGroupLinkedDevice, - countOfDevicesNeeded: 4, + countOfDevicesNeeded: 3, }); async function leaveGroupLinkedDevice(platform: SupportedPlatformsType, testInfo: TestInfo) { - const testGroupName = 'Leave group linked device'; - const { device1, device2, device3, device4 } = await openAppFourDevices(platform, testInfo); - const charlie = await linkedDevice(device3, device4, USERNAME.CHARLIE); - // Create users A, B and C - const [alice, bob] = await Promise.all([ - newUser(device1, USERNAME.ALICE), - newUser(device2, USERNAME.BOB), - ]); - // Create group with user A, user B and User C - await createGroup(platform, device1, alice, device2, bob, device3, charlie, testGroupName); - await sleepFor(1000); - await device3.clickOnElementAll(new ConversationSettings(device3)); + const testGroupName = 'Linked device group'; + const { + devices: { alice1, alice2, bob1 }, + prebuilt: { bob }, + } = await open_Alice2_Bob1_friends_group({ + platform, + groupName: testGroupName, + focusGroupConvo: true, + testInfo: testInfo, + }); + await bob1.clickOnElementAll(new ConversationSettings(bob1)); await sleepFor(1000); - await device3.clickOnElementAll(new LeaveGroupMenuItem(device3)); - await device3.checkModalStrings( + await bob1.clickOnElementAll(new LeaveGroupMenuItem(bob1)); + await bob1.checkModalStrings( englishStrippedStr('groupLeave').toString(), englishStrippedStr('groupLeaveDescription').withArgs({ group_name: testGroupName }).toString() ); - // Modal with Leave/Cancel - await device3.clickOnElementAll(new LeaveGroupConfirm(device3)); - // Check for control message - await sleepFor(5000); - await device4.onIOS().hasTextElementBeenDeleted('Conversation list item', testGroupName); - // Create control message for user leaving group + await bob1.clickOnElementAll(new LeaveGroupConfirm(bob1)); + await bob1.verifyElementNotPresent(new ConversationItem(bob1, testGroupName)); const groupMemberLeft = englishStrippedStr('groupMemberLeft') - .withArgs({ name: charlie.userName }) + .withArgs({ name: bob.userName }) .toString(); await Promise.all([ - device1.waitForControlMessageToBePresent(groupMemberLeft), - device2.waitForControlMessageToBePresent(groupMemberLeft), + alice1.waitForControlMessageToBePresent(groupMemberLeft), + alice2.waitForControlMessageToBePresent(groupMemberLeft), ]); - await closeApp(device1, device2, device3, device4); + await closeApp(alice1, alice2, bob1); } diff --git a/run/test/specs/review_negative.spec.ts b/run/test/specs/review_negative.spec.ts index 63c6c88fc..f35e2eab9 100644 --- a/run/test/specs/review_negative.spec.ts +++ b/run/test/specs/review_negative.spec.ts @@ -4,6 +4,7 @@ import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { TestSteps } from '../../types/allure'; import { bothPlatformsIt } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; +import { CloseSettings } from './locators'; import { ReviewPromptNeedsWorkButton, ReviewPromptNotNowButton, @@ -41,7 +42,7 @@ async function reviewPromptNegative(platform: SupportedPlatformsType, testInfo: await test.step(TestSteps.OPEN.PATH, async () => { await device.clickOnElementAll(new PathMenuItem(device)); await device.back(); - await device.back(); + await device.clickOnElementAll(new CloseSettings(device)) }); await test.step(TestSteps.VERIFY.SPECIFIC_MODAL('Enjoying Session'), async () => { await device.checkModalStrings( diff --git a/run/test/specs/review_once.spec.ts b/run/test/specs/review_once.spec.ts index 42fb61626..dc138051e 100644 --- a/run/test/specs/review_once.spec.ts +++ b/run/test/specs/review_once.spec.ts @@ -4,6 +4,7 @@ import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { TestSteps } from '../../types/allure'; import { androidIt } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; +import { CloseSettings } from './locators'; import { ModalHeading } from './locators/global'; import { PlusButton } from './locators/home'; import { PathMenuItem, UserSettings } from './locators/settings'; @@ -32,7 +33,7 @@ async function reviewPromptOnce(platform: SupportedPlatformsType, testInfo: Test await device.clickOnElementAll(new UserSettings(device)); await device.clickOnElementAll(new PathMenuItem(device)); await device.back(); - await device.back(); + await device.clickOnElementAll(new CloseSettings(device)); }); await test.step(TestSteps.VERIFY.GENERIC_MODAL, async () => { await device.checkModalStrings( diff --git a/run/test/specs/review_positive.spec.ts b/run/test/specs/review_positive.spec.ts index 7432b7439..6ce4dcfd1 100644 --- a/run/test/specs/review_positive.spec.ts +++ b/run/test/specs/review_positive.spec.ts @@ -4,6 +4,7 @@ import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { TestSteps } from '../../types/allure'; import { bothPlatformsIt } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; +import { CloseSettings } from './locators'; import { ReviewPromptItsGreatButton, ReviewPromptNotNowButton, @@ -37,7 +38,7 @@ async function reviewPromptPositive(platform: SupportedPlatformsType, testInfo: await device.clickOnElementAll(new UserSettings(device)); await device.clickOnElementAll(new PathMenuItem(device)); await device.back(); - await device.back(); + await device.clickOnElementAll(new CloseSettings(device)); }); await test.step(TestSteps.VERIFY.SPECIFIC_MODAL('Enjoying Session'), async () => { await device.checkModalStrings( diff --git a/run/test/specs/review_triggers.spec.ts b/run/test/specs/review_triggers.spec.ts index b19e91022..cc2b1ad25 100644 --- a/run/test/specs/review_triggers.spec.ts +++ b/run/test/specs/review_triggers.spec.ts @@ -5,6 +5,7 @@ import { TestSteps } from '../../types/allure'; import { DeviceWrapper } from '../../types/DeviceWrapper'; import { bothPlatformsIt } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; +import { CloseSettings } from './locators'; import { CopyURLButton } from './locators/global'; import { AppearanceMenuItem, @@ -71,7 +72,7 @@ for (const { titleSnippet, descriptionSnippet, testStepName, trigger } of review await test.step(testStepName, async () => { await device.clickOnElementAll(new UserSettings(device)); await trigger(device); - await device.back(); + await device.clickOnElementAll(new CloseSettings(device)); }); await test.step(TestSteps.VERIFY.SPECIFIC_MODAL('App Review'), async () => { await device.checkModalStrings( diff --git a/run/test/specs/state_builder/index.ts b/run/test/specs/state_builder/index.ts index 885ddea05..133f7a2db 100644 --- a/run/test/specs/state_builder/index.ts +++ b/run/test/specs/state_builder/index.ts @@ -203,23 +203,18 @@ export async function open_Alice1_Bob1_Charlie1_friends_group({ }; } -/** - * Open 4 devices, one for Alice, one for Bob, one for Charlie, and one extra, unlinked. - * This function is used for testing that we can do a bunch of actions without having a linked device, - * and then that linking a new device recovers the correct state. - */ -export async function open_Alice1_Bob1_Charlie1_Unknown1({ +export async function open_Alice1_Bob1_friends_group_Unknown1({ platform, groupName, - focusGroupConvo = true, + focusGroupConvo, testInfo, }: WithPlatform & WithFocusGroupConvo & { groupName: string; testInfo: TestInfo; }) { - const stateToBuildKey = '3friendsInGroup'; - const appsToOpen = 4; + const stateToBuildKey = '2friendsInGroup'; + const appsToOpen = 3; const result = await openAppsWithState({ platform, appsToOpen, @@ -229,8 +224,7 @@ export async function open_Alice1_Bob1_Charlie1_Unknown1({ }); result.devices[0].setDeviceIdentity('alice1'); result.devices[1].setDeviceIdentity('bob1'); - result.devices[2].setDeviceIdentity('charlie1'); - result.devices[3].setDeviceIdentity('unknown1'); // this device will be linked later + result.devices[2].setDeviceIdentity('unknown1'); // this device will be linked later const seedPhrases = result.prebuilt.users.map(m => m.seedPhrase); await linkDevices(result.devices.slice(0, -1), seedPhrases); @@ -238,21 +232,17 @@ export async function open_Alice1_Bob1_Charlie1_Unknown1({ const alice1 = result.devices[0]; const bob1 = result.devices[1]; - const charlie1 = result.devices[2]; const formattedDevices = { alice1, bob1, - charlie1, - unknown1: result.devices[3], // not assigned yet + unknown1: result.devices[2], // not assigned yet }; const alice = result.prebuilt.users[0]; const bob = result.prebuilt.users[1]; - const charlie = result.prebuilt.users[2]; - const formattedUsers: WithUsers<3> = { + const formattedUsers: WithUsers<2> = { alice, bob, - charlie, }; if (focusGroupConvo) { await focusConvoOnDevices({ @@ -393,3 +383,58 @@ export async function open_Alice2_Bob1_friends({ prebuilt: { ...formattedUsers }, }; } + +export async function open_Alice2_Bob1_friends_group({ + platform, + groupName, + focusGroupConvo = true, + testInfo, +}: WithPlatform & + WithFocusGroupConvo & { + groupName: string; + testInfo: TestInfo; + }) { + const stateToBuildKey = '2friendsInGroup'; + const appsToOpen = 3; + const result = await openAppsWithState({ + platform, + appsToOpen, + stateToBuildKey, + groupName, + testInfo, + }); + result.devices[0].setDeviceIdentity('alice1'); + result.devices[1].setDeviceIdentity('alice2'); + result.devices[2].setDeviceIdentity('bob1'); + const alice = result.prebuilt.users[0]; + const bob = result.prebuilt.users[1]; + // we want the first user to have the first 2 devices linked + const seedPhrases = [alice.seedPhrase, alice.seedPhrase, bob.seedPhrase]; + await linkDevices(result.devices, seedPhrases); + + const alice1 = result.devices[0]; + const alice2 = result.devices[1]; + const bob1 = result.devices[2]; + + const formattedUsers: WithUsers<2> = { + alice, + bob, + }; + + if (focusGroupConvo) { + await focusConvoOnDevices({ + devices: result.devices, + convoName: result.prebuilt.group.groupName, + }); + } + + return { + devices: { + // alice has two devices linked right away + alice1, + alice2, + bob1, + }, + prebuilt: { ...formattedUsers }, + }; +} diff --git a/run/test/specs/utils/binaries.ts b/run/test/specs/utils/binaries.ts index a30b5adb3..cbdebae1f 100644 --- a/run/test/specs/utils/binaries.ts +++ b/run/test/specs/utils/binaries.ts @@ -1,12 +1,21 @@ import { existsSync, lstatSync } from 'fs'; import { toNumber } from 'lodash'; +import * as path from 'path'; function existsAndFileOrThrow(path: string, id: string) { if (!existsSync(path) || !lstatSync(path).isFile()) { - throw new Error(`"${id}" does not exist at: ${path} or not a path`); + throw new Error(`"${id}" not found or not a file at: ${path}`); } } +const getAndroidSdkRoot = () => { + const sdkRoot = process.env.ANDROID_SDK_ROOT; + if (!sdkRoot) { + throw new Error('env variable `ANDROID_SDK_ROOT` needs to be set'); + } + return sdkRoot; +}; + export function getAndroidApk() { const fromEnv = process.env.ANDROID_APK; if (!fromEnv) { @@ -17,48 +26,53 @@ export function getAndroidApk() { } export const getAdbFullPath = () => { - const fromEnv = process.env.APPIUM_ADB_FULL_PATH; - if (!fromEnv) { - throw new Error('env variable `APPIUM_ADB_FULL_PATH` needs to be set'); - } - - existsAndFileOrThrow(fromEnv, 'adb'); - - return fromEnv; + const sdkRoot = getAndroidSdkRoot(); + const adbPath = path.join(sdkRoot, 'platform-tools', 'adb'); + existsAndFileOrThrow(adbPath, 'adb'); + return adbPath; }; export const getEmulatorFullPath = () => { - const fromEnv = process.env.EMULATOR_FULL_PATH; - - if (!fromEnv) { - throw new Error('env variable `EMULATOR_FULL_PATH` needs to be set'); - } - existsAndFileOrThrow(fromEnv, 'EMULATOR_FULL_PATH'); - - return fromEnv; + const sdkRoot = getAndroidSdkRoot(); + const emulatorPath = path.join(sdkRoot, 'emulator', 'emulator'); + existsAndFileOrThrow(emulatorPath, 'emulator'); + return emulatorPath; }; export const getAvdManagerFullPath = () => { - const fromEnv = process.env.AVD_MANAGER_FULL_PATH; - - if (!fromEnv) { - throw new Error('env variable `AVD_MANAGER_FULL_PATH` needs to be set'); + const sdkRoot = getAndroidSdkRoot(); + // Try multiple possible locations + const possiblePaths = [ + path.join(sdkRoot, 'cmdline-tools', 'latest', 'bin', 'avdmanager'), + path.join(sdkRoot, 'cmdline-tools', 'tools', 'bin', 'avdmanager'), + path.join(sdkRoot, 'tools', 'bin', 'avdmanager'), + ]; + + for (const path of possiblePaths) { + if (existsSync(path) && lstatSync(path).isFile()) { + return path; + } } - existsAndFileOrThrow(fromEnv, 'AVD_MANAGER_FULL_PATH'); - return fromEnv; + throw new Error(`avdmanager not found in any expected location under ${sdkRoot}`); }; export const getSdkManagerFullPath = () => { - const fromEnv = process.env.SDK_MANAGER_FULL_PATH; - - if (!fromEnv) { - throw new Error('env variable `SDK_MANAGER_FULL_PATH` needs to be set'); + const sdkRoot = getAndroidSdkRoot(); + // Try multiple possible locations + const possiblePaths = [ + path.join(sdkRoot, 'cmdline-tools', 'latest', 'bin', 'sdkmanager'), + path.join(sdkRoot, 'cmdline-tools', 'tools', 'bin', 'sdkmanager'), + path.join(sdkRoot, 'tools', 'bin', 'sdkmanager'), + ]; + + for (const path of possiblePaths) { + if (existsSync(path) && lstatSync(path).isFile()) { + return path; + } } - existsAndFileOrThrow(fromEnv, 'SDK_MANAGER_FULL_PATH'); - - return fromEnv; + throw new Error(`sdkmanager not found in any expected location under ${sdkRoot}`); }; export const getAndroidSystemImageToUse = () => { diff --git a/run/test/specs/utils/utilities.ts b/run/test/specs/utils/utilities.ts index b89a2464b..236a30a2c 100644 --- a/run/test/specs/utils/utilities.ts +++ b/run/test/specs/utils/utilities.ts @@ -20,7 +20,8 @@ export async function runScriptAndLog(toRun: string, verbose = false): Promise&2 + return 1 + fi + + # Extract and setup + unzip -d $ANDROID_SDK_ROOT /tmp/$ANDROID_CMD && \ + mkdir -p $ANDROID_SDK_ROOT/cmdline-tools/tools && \ + cd $ANDROID_SDK_ROOT/cmdline-tools && \ + mv NOTICE.txt source.properties bin lib tools/ && \ + cd $ANDROID_SDK_ROOT/cmdline-tools/tools && \ + ls yes Y | sdkmanager --licenses yes Y | sdkmanager --verbose --no_https ${ANDROID_SDK_PACKAGES} @@ -49,24 +91,24 @@ function create_emulators() { adb start-server - for i in {1..4} + for i in $(seq 1 $EMULATOR_COUNT) do echo "no" | avdmanager --verbose create avd --force --name "emulator$i" --device "${EMULATOR_DEVICE}" --package "${EMULATOR_PACKAGE}" - # Path to the AVD's config.ini file - CONFIG_FILE="$HOME/.android/avd/emulator$i.avd/config.ini" - - # Set the RAM size to 4GB (4192MB) - sed -i 's/^hw\.ramSize=.*/hw.ramSize=4192/' "$CONFIG_FILE" - + + # Configure RAM for each AVD + local config_file="$HOME/.android/avd/emulator$i.avd/config.ini" + if [[ "$OSTYPE" == "darwin"* ]]; then + sed -i '' "s/^hw\.ramSize=.*/hw.ramSize=${RAM_SIZE}/" "$config_file" + else + sed -i "s/^hw\.ramSize=.*/hw.ramSize=${RAM_SIZE}/" "$config_file" + fi done - - cd } function start_for_snapshots() { - for i in {1..4} + for i in $(seq 1 $EMULATOR_COUNT) do - DISPLAY=:0 emulator @emulator$i -gpu host -accel on -no-snapshot-load & + $EMULATOR_BIN @emulator$i -gpu host -accel on -no-snapshot-load & sleep 20 done } @@ -74,34 +116,44 @@ function start_for_snapshots() { # let the emulators start and be ready (check cpu usage) before calling this. # We want to take a snapshot woth emulators state as "done" as we can function force_save_snapshots() { - values=("5554" "5556" "5558" "5560") - for val in "${values[@]}" + # Dynamic port generation based on emulator count + for i in $(seq 1 $EMULATOR_COUNT) do - adb -s emulator-$val emu avd snapshot save plop.snapshot + port=$((5554 + (i-1)*2)) + adb -s emulator-$port emu avd snapshot save plop.snapshot done } function killall_emulators() { - killall qemu-system-x86_64; + killall "$EMULATOR_PROCESS" 2>/dev/null || true } function start_with_snapshots() { - for i in {1..4}; do - EMU_CONFIG_FILE="$HOME/.android/avd/emulator$i.avd/emulator-user.ini" - # Set window position - sed -i "s/^window.x.*/window.x=$(( 100 + (i-1) * 400))/" "$EMU_CONFIG_FILE" - - DISPLAY=:0 emulator @emulator$i -gpu host -accel on -no-snapshot-save -snapshot plop.snapshot -force-snapshot-load & - - sleep 5 - done + for i in $(seq 1 $EMULATOR_COUNT); do + if [[ "$OSTYPE" == "darwin"* ]]; then + # Mac: Headless with 9 emulators + $EMULATOR_BIN @emulator$i \ + -no-window \ + -no-snapshot-save \ + -snapshot plop.snapshot \ + -force-snapshot-load & + else + # Linux: Keep as-is + EMU_CONFIG_FILE="$HOME/.android/avd/emulator$i.avd/emulator-user.ini" + sed -i "s/^window.x.*/window.x=$(( 100 + (i-1) * 400))/" "$EMU_CONFIG_FILE" + DISPLAY=:0 $EMULATOR_BIN @emulator$i -gpu host -accel on -no-snapshot-save -snapshot plop.snapshot -force-snapshot-load & + fi + + sleep 5 + done } function wait_for_emulators() { - for port in 5554 5556 5558 5560 + for i in $(seq 1 $EMULATOR_COUNT) do - for i in {1..60}; do + port=$((5554 + (i-1)*2)) + for j in {1..60}; do if adb -s emulator-$port shell getprop sys.boot_completed 2>/dev/null | grep -q "1"; then echo "emulator-$port booted" break diff --git a/yarn.lock b/yarn.lock index 82c08a783..085930c0c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -266,12 +266,12 @@ __metadata: languageName: node linkType: hard -"@emnapi/runtime@npm:^1.4.3": - version: 1.4.3 - resolution: "@emnapi/runtime@npm:1.4.3" +"@emnapi/runtime@npm:^1.4.4": + version: 1.4.5 + resolution: "@emnapi/runtime@npm:1.4.5" dependencies: tslib: "npm:^2.4.0" - checksum: 10c0/3b7ab72d21cb4e034f07df80165265f85f445ef3f581d1bc87b67e5239428baa00200b68a7d5e37a0425c3a78320b541b07f76c5530f6f6f95336a6294ebf30b + checksum: 10c0/37a0278be5ac81e918efe36f1449875cbafba947039c53c65a1f8fc238001b866446fc66041513b286baaff5d6f9bec667f5164b3ca481373a8d9cb65bfc984b languageName: node linkType: hard @@ -293,39 +293,30 @@ __metadata: languageName: node linkType: hard -"@eslint/config-array@npm:^0.20.1": - version: 0.20.1 - resolution: "@eslint/config-array@npm:0.20.1" +"@eslint/config-array@npm:^0.21.0": + version: 0.21.0 + resolution: "@eslint/config-array@npm:0.21.0" dependencies: "@eslint/object-schema": "npm:^2.1.6" debug: "npm:^4.3.1" minimatch: "npm:^3.1.2" - checksum: 10c0/709108c3925d83c2166024646829ab61ba5fa85c6568daefd32508899f46ed8dc36d7153042df6dcc7e58ad543bc93298b646575daecb5eb4e39a43d838dab42 - languageName: node - linkType: hard - -"@eslint/config-helpers@npm:^0.2.1": - version: 0.2.3 - resolution: "@eslint/config-helpers@npm:0.2.3" - checksum: 10c0/8fd36d7f33013628787947c81894807c7498b31eacf6648efa6d7c7a99aac6bf0d59a8a4d14f968ec2aeebefb76a1a7e4fd4cd556a296323d4711b3d7a7cda22 + checksum: 10c0/0ea801139166c4aa56465b309af512ef9b2d3c68f9198751bbc3e21894fe70f25fbf26e1b0e9fffff41857bc21bfddeee58649ae6d79aadcd747db0c5dca771f languageName: node linkType: hard -"@eslint/core@npm:^0.14.0": - version: 0.14.0 - resolution: "@eslint/core@npm:0.14.0" - dependencies: - "@types/json-schema": "npm:^7.0.15" - checksum: 10c0/259f279445834ba2d2cbcc18e9d43202a4011fde22f29d5fb802181d66e0f6f0bd1f6b4b4b46663451f545d35134498231bd5e656e18d9034a457824b92b7741 +"@eslint/config-helpers@npm:^0.3.1": + version: 0.3.1 + resolution: "@eslint/config-helpers@npm:0.3.1" + checksum: 10c0/f6c5b3a0b76a0d7d84cc93e310c259e6c3e0792ddd0a62c5fc0027796ffae44183432cb74b2c2b1162801ee1b1b34a6beb5d90a151632b4df7349f994146a856 languageName: node linkType: hard -"@eslint/core@npm:^0.15.0": - version: 0.15.0 - resolution: "@eslint/core@npm:0.15.0" +"@eslint/core@npm:^0.15.2": + version: 0.15.2 + resolution: "@eslint/core@npm:0.15.2" dependencies: "@types/json-schema": "npm:^7.0.15" - checksum: 10c0/9882c69acfe29743ce473a619d5248589c6687561afaabe8ec8d7ffed07592db16edcca3af022f33ea92fe5f6cfbe3545ee53e89292579d22a944ebaeddcf72d + checksum: 10c0/c17a6dc4f5a6006ecb60165cc38bcd21fefb4a10c7a2578a0cfe5813bbd442531a87ed741da5adab5eb678e8e693fda2e2b14555b035355537e32bcec367ea17 languageName: node linkType: hard @@ -346,10 +337,10 @@ __metadata: languageName: node linkType: hard -"@eslint/js@npm:9.29.0, @eslint/js@npm:^9.14.0": - version: 9.29.0 - resolution: "@eslint/js@npm:9.29.0" - checksum: 10c0/d0ccf37063fa27a3fae9347cb044f84ca10b5a2fa19ffb2b3fedf3b96843ac1ff359ea9f0ab0e80f2f16fda4cb0dc61ea0fed0375090f050fe0a029e7d6de3a3 +"@eslint/js@npm:9.34.0, @eslint/js@npm:^9.14.0": + version: 9.34.0 + resolution: "@eslint/js@npm:9.34.0" + checksum: 10c0/53f1bfd2a374683d9382a6850354555f6e89a88416c34a5d34e9fbbaf717e97c2b06300e8f93e5eddba8bda8951ccab7f93a680e56ded1a3d21d526019e69bab languageName: node linkType: hard @@ -360,13 +351,13 @@ __metadata: languageName: node linkType: hard -"@eslint/plugin-kit@npm:^0.3.1": - version: 0.3.2 - resolution: "@eslint/plugin-kit@npm:0.3.2" +"@eslint/plugin-kit@npm:^0.3.5": + version: 0.3.5 + resolution: "@eslint/plugin-kit@npm:0.3.5" dependencies: - "@eslint/core": "npm:^0.15.0" + "@eslint/core": "npm:^0.15.2" levn: "npm:^0.4.1" - checksum: 10c0/e069b0a46eb9fa595a1ac7dea4540a9daa493afba88875ee054e9117609c1c41555e779303cb4cff36cf88f603ba6eba2556a927e8ced77002828206ee17fc7e + checksum: 10c0/c178c1b58c574200c0fd125af3e4bc775daba7ce434ba6d1eeaf9bcb64b2e9fea75efabffb3ed3ab28858e55a016a5efa95f509994ee4341b341199ca630b89e languageName: node linkType: hard @@ -408,11 +399,11 @@ __metadata: languageName: node linkType: hard -"@img/sharp-darwin-arm64@npm:0.34.2": - version: 0.34.2 - resolution: "@img/sharp-darwin-arm64@npm:0.34.2" +"@img/sharp-darwin-arm64@npm:0.34.3": + version: 0.34.3 + resolution: "@img/sharp-darwin-arm64@npm:0.34.3" dependencies: - "@img/sharp-libvips-darwin-arm64": "npm:1.1.0" + "@img/sharp-libvips-darwin-arm64": "npm:1.2.0" dependenciesMeta: "@img/sharp-libvips-darwin-arm64": optional: true @@ -420,11 +411,11 @@ __metadata: languageName: node linkType: hard -"@img/sharp-darwin-x64@npm:0.34.2": - version: 0.34.2 - resolution: "@img/sharp-darwin-x64@npm:0.34.2" +"@img/sharp-darwin-x64@npm:0.34.3": + version: 0.34.3 + resolution: "@img/sharp-darwin-x64@npm:0.34.3" dependencies: - "@img/sharp-libvips-darwin-x64": "npm:1.1.0" + "@img/sharp-libvips-darwin-x64": "npm:1.2.0" dependenciesMeta: "@img/sharp-libvips-darwin-x64": optional: true @@ -432,74 +423,74 @@ __metadata: languageName: node linkType: hard -"@img/sharp-libvips-darwin-arm64@npm:1.1.0": - version: 1.1.0 - resolution: "@img/sharp-libvips-darwin-arm64@npm:1.1.0" +"@img/sharp-libvips-darwin-arm64@npm:1.2.0": + version: 1.2.0 + resolution: "@img/sharp-libvips-darwin-arm64@npm:1.2.0" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@img/sharp-libvips-darwin-x64@npm:1.1.0": - version: 1.1.0 - resolution: "@img/sharp-libvips-darwin-x64@npm:1.1.0" +"@img/sharp-libvips-darwin-x64@npm:1.2.0": + version: 1.2.0 + resolution: "@img/sharp-libvips-darwin-x64@npm:1.2.0" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@img/sharp-libvips-linux-arm64@npm:1.1.0": - version: 1.1.0 - resolution: "@img/sharp-libvips-linux-arm64@npm:1.1.0" +"@img/sharp-libvips-linux-arm64@npm:1.2.0": + version: 1.2.0 + resolution: "@img/sharp-libvips-linux-arm64@npm:1.2.0" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@img/sharp-libvips-linux-arm@npm:1.1.0": - version: 1.1.0 - resolution: "@img/sharp-libvips-linux-arm@npm:1.1.0" +"@img/sharp-libvips-linux-arm@npm:1.2.0": + version: 1.2.0 + resolution: "@img/sharp-libvips-linux-arm@npm:1.2.0" conditions: os=linux & cpu=arm & libc=glibc languageName: node linkType: hard -"@img/sharp-libvips-linux-ppc64@npm:1.1.0": - version: 1.1.0 - resolution: "@img/sharp-libvips-linux-ppc64@npm:1.1.0" +"@img/sharp-libvips-linux-ppc64@npm:1.2.0": + version: 1.2.0 + resolution: "@img/sharp-libvips-linux-ppc64@npm:1.2.0" conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard -"@img/sharp-libvips-linux-s390x@npm:1.1.0": - version: 1.1.0 - resolution: "@img/sharp-libvips-linux-s390x@npm:1.1.0" +"@img/sharp-libvips-linux-s390x@npm:1.2.0": + version: 1.2.0 + resolution: "@img/sharp-libvips-linux-s390x@npm:1.2.0" conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard -"@img/sharp-libvips-linux-x64@npm:1.1.0": - version: 1.1.0 - resolution: "@img/sharp-libvips-linux-x64@npm:1.1.0" +"@img/sharp-libvips-linux-x64@npm:1.2.0": + version: 1.2.0 + resolution: "@img/sharp-libvips-linux-x64@npm:1.2.0" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@img/sharp-libvips-linuxmusl-arm64@npm:1.1.0": - version: 1.1.0 - resolution: "@img/sharp-libvips-linuxmusl-arm64@npm:1.1.0" +"@img/sharp-libvips-linuxmusl-arm64@npm:1.2.0": + version: 1.2.0 + resolution: "@img/sharp-libvips-linuxmusl-arm64@npm:1.2.0" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@img/sharp-libvips-linuxmusl-x64@npm:1.1.0": - version: 1.1.0 - resolution: "@img/sharp-libvips-linuxmusl-x64@npm:1.1.0" +"@img/sharp-libvips-linuxmusl-x64@npm:1.2.0": + version: 1.2.0 + resolution: "@img/sharp-libvips-linuxmusl-x64@npm:1.2.0" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@img/sharp-linux-arm64@npm:0.34.2": - version: 0.34.2 - resolution: "@img/sharp-linux-arm64@npm:0.34.2" +"@img/sharp-linux-arm64@npm:0.34.3": + version: 0.34.3 + resolution: "@img/sharp-linux-arm64@npm:0.34.3" dependencies: - "@img/sharp-libvips-linux-arm64": "npm:1.1.0" + "@img/sharp-libvips-linux-arm64": "npm:1.2.0" dependenciesMeta: "@img/sharp-libvips-linux-arm64": optional: true @@ -507,11 +498,11 @@ __metadata: languageName: node linkType: hard -"@img/sharp-linux-arm@npm:0.34.2": - version: 0.34.2 - resolution: "@img/sharp-linux-arm@npm:0.34.2" +"@img/sharp-linux-arm@npm:0.34.3": + version: 0.34.3 + resolution: "@img/sharp-linux-arm@npm:0.34.3" dependencies: - "@img/sharp-libvips-linux-arm": "npm:1.1.0" + "@img/sharp-libvips-linux-arm": "npm:1.2.0" dependenciesMeta: "@img/sharp-libvips-linux-arm": optional: true @@ -519,11 +510,23 @@ __metadata: languageName: node linkType: hard -"@img/sharp-linux-s390x@npm:0.34.2": - version: 0.34.2 - resolution: "@img/sharp-linux-s390x@npm:0.34.2" +"@img/sharp-linux-ppc64@npm:0.34.3": + version: 0.34.3 + resolution: "@img/sharp-linux-ppc64@npm:0.34.3" + dependencies: + "@img/sharp-libvips-linux-ppc64": "npm:1.2.0" + dependenciesMeta: + "@img/sharp-libvips-linux-ppc64": + optional: true + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-linux-s390x@npm:0.34.3": + version: 0.34.3 + resolution: "@img/sharp-linux-s390x@npm:0.34.3" dependencies: - "@img/sharp-libvips-linux-s390x": "npm:1.1.0" + "@img/sharp-libvips-linux-s390x": "npm:1.2.0" dependenciesMeta: "@img/sharp-libvips-linux-s390x": optional: true @@ -531,11 +534,11 @@ __metadata: languageName: node linkType: hard -"@img/sharp-linux-x64@npm:0.34.2": - version: 0.34.2 - resolution: "@img/sharp-linux-x64@npm:0.34.2" +"@img/sharp-linux-x64@npm:0.34.3": + version: 0.34.3 + resolution: "@img/sharp-linux-x64@npm:0.34.3" dependencies: - "@img/sharp-libvips-linux-x64": "npm:1.1.0" + "@img/sharp-libvips-linux-x64": "npm:1.2.0" dependenciesMeta: "@img/sharp-libvips-linux-x64": optional: true @@ -543,11 +546,11 @@ __metadata: languageName: node linkType: hard -"@img/sharp-linuxmusl-arm64@npm:0.34.2": - version: 0.34.2 - resolution: "@img/sharp-linuxmusl-arm64@npm:0.34.2" +"@img/sharp-linuxmusl-arm64@npm:0.34.3": + version: 0.34.3 + resolution: "@img/sharp-linuxmusl-arm64@npm:0.34.3" dependencies: - "@img/sharp-libvips-linuxmusl-arm64": "npm:1.1.0" + "@img/sharp-libvips-linuxmusl-arm64": "npm:1.2.0" dependenciesMeta: "@img/sharp-libvips-linuxmusl-arm64": optional: true @@ -555,11 +558,11 @@ __metadata: languageName: node linkType: hard -"@img/sharp-linuxmusl-x64@npm:0.34.2": - version: 0.34.2 - resolution: "@img/sharp-linuxmusl-x64@npm:0.34.2" +"@img/sharp-linuxmusl-x64@npm:0.34.3": + version: 0.34.3 + resolution: "@img/sharp-linuxmusl-x64@npm:0.34.3" dependencies: - "@img/sharp-libvips-linuxmusl-x64": "npm:1.1.0" + "@img/sharp-libvips-linuxmusl-x64": "npm:1.2.0" dependenciesMeta: "@img/sharp-libvips-linuxmusl-x64": optional: true @@ -567,32 +570,32 @@ __metadata: languageName: node linkType: hard -"@img/sharp-wasm32@npm:0.34.2": - version: 0.34.2 - resolution: "@img/sharp-wasm32@npm:0.34.2" +"@img/sharp-wasm32@npm:0.34.3": + version: 0.34.3 + resolution: "@img/sharp-wasm32@npm:0.34.3" dependencies: - "@emnapi/runtime": "npm:^1.4.3" + "@emnapi/runtime": "npm:^1.4.4" conditions: cpu=wasm32 languageName: node linkType: hard -"@img/sharp-win32-arm64@npm:0.34.2": - version: 0.34.2 - resolution: "@img/sharp-win32-arm64@npm:0.34.2" +"@img/sharp-win32-arm64@npm:0.34.3": + version: 0.34.3 + resolution: "@img/sharp-win32-arm64@npm:0.34.3" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@img/sharp-win32-ia32@npm:0.34.2": - version: 0.34.2 - resolution: "@img/sharp-win32-ia32@npm:0.34.2" +"@img/sharp-win32-ia32@npm:0.34.3": + version: 0.34.3 + resolution: "@img/sharp-win32-ia32@npm:0.34.3" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@img/sharp-win32-x64@npm:0.34.2": - version: 0.34.2 - resolution: "@img/sharp-win32-x64@npm:0.34.2" +"@img/sharp-win32-x64@npm:0.34.3": + version: 0.34.3 + resolution: "@img/sharp-win32-x64@npm:0.34.3" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -644,9 +647,9 @@ __metadata: linkType: hard "@jridgewell/sourcemap-codec@npm:^1.4.10": - version: 1.5.0 - resolution: "@jridgewell/sourcemap-codec@npm:1.5.0" - checksum: 10c0/2eb864f276eb1096c3c11da3e9bb518f6d9fc0023c78344cdc037abadc725172c70314bdb360f2d4b7bffec7f5d657ce006816bc5d4ecb35e61b66132db00c18 + version: 1.5.5 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.5" + checksum: 10c0/f9e538f302b63c0ebc06eecb1dd9918dd4289ed36147a0ddce35d6ea4d7ebbda243cda7b2213b6a5e1d8087a298d5cf630fb2bd39329cdecb82017023f6081a0 languageName: node linkType: hard @@ -758,13 +761,13 @@ __metadata: linkType: hard "@playwright/test@npm:^1.45.1": - version: 1.53.1 - resolution: "@playwright/test@npm:1.53.1" + version: 1.55.0 + resolution: "@playwright/test@npm:1.55.0" dependencies: - playwright: "npm:1.53.1" + playwright: "npm:1.55.0" bin: playwright: cli.js - checksum: 10c0/f2ef7899ca6bc178c9f2ba6c8633d0bbeb5ba135048e9df01ecb949c6f743811ba5ef76d495f619454074c81dbfa28be12e4c0a1224bb2af0d4cb403182c716f + checksum: 10c0/e68b59cd8271f1b57c0649fc0562ab2d5f6bba8c3653dd7bd52ca1338dc380fde34588d0254e3cd3f0f2b20af04a80dfb080419ceb7475990bb2fc4d8c474984 languageName: node linkType: hard @@ -889,13 +892,12 @@ __metadata: linkType: hard "@sinonjs/samsam@npm:^8.0.1": - version: 8.0.2 - resolution: "@sinonjs/samsam@npm:8.0.2" + version: 8.0.3 + resolution: "@sinonjs/samsam@npm:8.0.3" dependencies: "@sinonjs/commons": "npm:^3.0.1" - lodash.get: "npm:^4.4.2" type-detect: "npm:^4.1.0" - checksum: 10c0/31d74c415040161f2963a202d7f866bedbb5a9b522a74b08a17086c15a75c3ef2893eecebb0c65a7b1603ef4ebdf83fa73cbe384b4cd679944918ed833200443 + checksum: 10c0/9bf57a8f8a484b3455696786e1679db7f0d6017de62099ee304bd364281fcb20895b7c6b05292aa10fecf76df27691e914fc3e1cb8a56d88c027e87d869dcf0c languageName: node linkType: hard @@ -1026,36 +1028,36 @@ __metadata: linkType: hard "@types/lodash@npm:^4.14.191, @types/lodash@npm:^4.14.192": - version: 4.17.18 - resolution: "@types/lodash@npm:4.17.18" - checksum: 10c0/d25f86941990403d59dcaae42b42fc9fef55a0a7f398790517e7189300183e425a94127594cbeaf9b5fcdc4f6c2b285e34f4301fb56c92f81ccd8505a41ab5f5 + version: 4.17.20 + resolution: "@types/lodash@npm:4.17.20" + checksum: 10c0/98cdd0faae22cbb8079a01a3bb65aa8f8c41143367486c1cbf5adc83f16c9272a2a5d2c1f541f61d0d73da543c16ee1d21cf2ef86cb93cd0cc0ac3bced6dd88f languageName: node linkType: hard "@types/node@npm:*": - version: 24.0.3 - resolution: "@types/node@npm:24.0.3" + version: 24.3.0 + resolution: "@types/node@npm:24.3.0" dependencies: - undici-types: "npm:~7.8.0" - checksum: 10c0/9c3c4e87600d1cf11e291c2fd4bfd806a615455463c30a0ef6dc9c801b3423344d9b82b8084e3ccabce485a7421ebb61a66e9676181bd7d9aea4759998a120d5 + undici-types: "npm:~7.10.0" + checksum: 10c0/96bdeca01f690338957c2dcc92cb9f76c262c10398f8d91860865464412b0f9d309c24d9b03d0bdd26dd47fa7ee3f8227893d5c89bc2009d919a525a22512030 languageName: node linkType: hard "@types/node@npm:^20.14.10": - version: 20.19.1 - resolution: "@types/node@npm:20.19.1" + version: 20.19.11 + resolution: "@types/node@npm:20.19.11" dependencies: undici-types: "npm:~6.21.0" - checksum: 10c0/4f1c3c8ec24c79af6802b376fa307904abf19accb9ac291de0bfc02220494c8b027d3ef733dbf64cc09b37594f22f679a15eabb30f3785bcfcc13bd9bbd8c0e2 + checksum: 10c0/9eecc4be04f1a8afbb8f8059b322fd0bbceeb02f96669bbaa52fb0b264c2e3269432a8833ada4be7b335e18d6b438b2d2c0274f5b3f54cc2081cb7c5374a6561 languageName: node linkType: hard "@types/node@npm:^22.2.0": - version: 22.15.32 - resolution: "@types/node@npm:22.15.32" + version: 22.18.0 + resolution: "@types/node@npm:22.18.0" dependencies: undici-types: "npm:~6.21.0" - checksum: 10c0/63a2fa52adf1134d1b3bee8b1862d4b8e4550fffc190551068d3d41a41d9e5c0c8f1cb81faa18767b260637360f662115c26c5e4e7718868ead40c4a57cbc0e3 + checksum: 10c0/02cce4493eee8408e66e76fcad164f33c0600ed0854ad08e5519a76a06402da5b589b278cf71bc975c9e014f2668bdf758bc3be7fed63bdbfd0900495372797c languageName: node linkType: hard @@ -1130,24 +1132,24 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:8.34.1": - version: 8.34.1 - resolution: "@typescript-eslint/eslint-plugin@npm:8.34.1" +"@typescript-eslint/eslint-plugin@npm:8.41.0": + version: 8.41.0 + resolution: "@typescript-eslint/eslint-plugin@npm:8.41.0" dependencies: "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:8.34.1" - "@typescript-eslint/type-utils": "npm:8.34.1" - "@typescript-eslint/utils": "npm:8.34.1" - "@typescript-eslint/visitor-keys": "npm:8.34.1" + "@typescript-eslint/scope-manager": "npm:8.41.0" + "@typescript-eslint/type-utils": "npm:8.41.0" + "@typescript-eslint/utils": "npm:8.41.0" + "@typescript-eslint/visitor-keys": "npm:8.41.0" graphemer: "npm:^1.4.0" ignore: "npm:^7.0.0" natural-compare: "npm:^1.4.0" ts-api-utils: "npm:^2.1.0" peerDependencies: - "@typescript-eslint/parser": ^8.34.1 + "@typescript-eslint/parser": ^8.41.0 eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.9.0" - checksum: 10c0/f1c9f25e4fe4b59622312dfa0ca1e80fa7945296ba5c04362a5fda084a17e23a6b98dac331f5a13bcb1ba34a2b598a3f5c41aa288f0c51fe60196e912954e56a + typescript: ">=4.8.4 <6.0.0" + checksum: 10c0/29812ee5deeae65e67db29faa8d96bc70255c45788f342b11838850ea29a96e4331622cad3e703ffacaa895372845d44fd6b04786117c78f1a027595adff2e62 languageName: node linkType: hard @@ -1175,19 +1177,19 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/parser@npm:8.34.1": - version: 8.34.1 - resolution: "@typescript-eslint/parser@npm:8.34.1" +"@typescript-eslint/parser@npm:8.41.0": + version: 8.41.0 + resolution: "@typescript-eslint/parser@npm:8.41.0" dependencies: - "@typescript-eslint/scope-manager": "npm:8.34.1" - "@typescript-eslint/types": "npm:8.34.1" - "@typescript-eslint/typescript-estree": "npm:8.34.1" - "@typescript-eslint/visitor-keys": "npm:8.34.1" + "@typescript-eslint/scope-manager": "npm:8.41.0" + "@typescript-eslint/types": "npm:8.41.0" + "@typescript-eslint/typescript-estree": "npm:8.41.0" + "@typescript-eslint/visitor-keys": "npm:8.41.0" debug: "npm:^4.3.4" peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.9.0" - checksum: 10c0/bf8070245d53ef6926ff6630bb72f245923f545304e2a61508fb944802a83fed8eab961d9010956d07999d51afdfbbec82aea9d6185295551a7c17c00d759183 + typescript: ">=4.8.4 <6.0.0" + checksum: 10c0/ca13ff505e9253aee761741f96714cd65a296bbfcac961efbbf7a909ff3d180b2142a23db0a2a5e50b928fa56586528b7e47ba6301089dd850945018dbf2ef50 languageName: node linkType: hard @@ -1208,29 +1210,16 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/project-service@npm:8.34.1": - version: 8.34.1 - resolution: "@typescript-eslint/project-service@npm:8.34.1" - dependencies: - "@typescript-eslint/tsconfig-utils": "npm:^8.34.1" - "@typescript-eslint/types": "npm:^8.34.1" - debug: "npm:^4.3.4" - peerDependencies: - typescript: ">=4.8.4 <5.9.0" - checksum: 10c0/9333a890625f6777054db17a6b299281ae7502bb7615261d15b885a75b8cf65fc91591389c93b37ecd14b651d8e94851dac8718e5dcc8ed0600533535dae855c - languageName: node - linkType: hard - -"@typescript-eslint/project-service@npm:8.35.1": - version: 8.35.1 - resolution: "@typescript-eslint/project-service@npm:8.35.1" +"@typescript-eslint/project-service@npm:8.41.0": + version: 8.41.0 + resolution: "@typescript-eslint/project-service@npm:8.41.0" dependencies: - "@typescript-eslint/tsconfig-utils": "npm:^8.35.1" - "@typescript-eslint/types": "npm:^8.35.1" + "@typescript-eslint/tsconfig-utils": "npm:^8.41.0" + "@typescript-eslint/types": "npm:^8.41.0" debug: "npm:^4.3.4" peerDependencies: - typescript: ">=4.8.4 <5.9.0" - checksum: 10c0/f8e88d773d7e9f193a05b4daeca1e7571fa0059b36ffad291fc6d83c9df94fbe38c935e076ae29e755bcb6008c4ee5c1073ebb2077258c5c0b53c76a23eb3c16 + typescript: ">=4.8.4 <6.0.0" + checksum: 10c0/907ba880fcaf0805fc97012b431536b5b06db6ae4a0095708f9d9a4406feddabd964f09ea4ca99d8fa7bd141dbcc9496f1a9eb6683361a6bb01fb714a361126c languageName: node linkType: hard @@ -1244,41 +1233,22 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:8.34.1": - version: 8.34.1 - resolution: "@typescript-eslint/scope-manager@npm:8.34.1" - dependencies: - "@typescript-eslint/types": "npm:8.34.1" - "@typescript-eslint/visitor-keys": "npm:8.34.1" - checksum: 10c0/2af608fa3900f4726322e33bf4f3a376fdace3ac0f310cf7d9256bbc2905c3896138176a47dd195d2c2229f27fe43f5deb4bc7729db2eb18389926dedea78077 - languageName: node - linkType: hard - -"@typescript-eslint/scope-manager@npm:8.35.1": - version: 8.35.1 - resolution: "@typescript-eslint/scope-manager@npm:8.35.1" +"@typescript-eslint/scope-manager@npm:8.41.0": + version: 8.41.0 + resolution: "@typescript-eslint/scope-manager@npm:8.41.0" dependencies: - "@typescript-eslint/types": "npm:8.35.1" - "@typescript-eslint/visitor-keys": "npm:8.35.1" - checksum: 10c0/ddfa0b81f47402874efcdd8e0857142600d90fc4e827243ed0fd058731e77e4beb8f5a60425117d1d4146d84437f538cf303f7bfebbd0f02733b202aa30a8393 + "@typescript-eslint/types": "npm:8.41.0" + "@typescript-eslint/visitor-keys": "npm:8.41.0" + checksum: 10c0/6b339ac1fc37a1e05dc6de421db9f9b138c357497ec87af2471ad30e48c78b4979d3da40943a1c81fc85d1537326a4f938843434db63d29eff414b9364daf8e8 languageName: node linkType: hard -"@typescript-eslint/tsconfig-utils@npm:8.34.1, @typescript-eslint/tsconfig-utils@npm:^8.34.1": - version: 8.34.1 - resolution: "@typescript-eslint/tsconfig-utils@npm:8.34.1" - peerDependencies: - typescript: ">=4.8.4 <5.9.0" - checksum: 10c0/8d1ead8b7c279b48e2ed96f083ec119a9aeea1ca9cdd40576ec271b996b9fd8cfa0ddb0aafbb4e14bc27fc62c69c5be66d39b1de68eab9ddd7f1861da267423d - languageName: node - linkType: hard - -"@typescript-eslint/tsconfig-utils@npm:8.35.1, @typescript-eslint/tsconfig-utils@npm:^8.35.1": - version: 8.35.1 - resolution: "@typescript-eslint/tsconfig-utils@npm:8.35.1" +"@typescript-eslint/tsconfig-utils@npm:8.41.0, @typescript-eslint/tsconfig-utils@npm:^8.41.0": + version: 8.41.0 + resolution: "@typescript-eslint/tsconfig-utils@npm:8.41.0" peerDependencies: - typescript: ">=4.8.4 <5.9.0" - checksum: 10c0/a11b53e05fbc59eff3f95619847fb7222d8b2aa613e602524c9b700be3ce0d48bcf5e5932869df4658f514bd2cdc87c857d484472af3f3f3adf88b6e7e1c26f3 + typescript: ">=4.8.4 <6.0.0" + checksum: 10c0/98618a536b9cb071eacba2970ce2ca1b9243de78f4604c2e350823a5275b9d7d15238dbe6acd197c30c0b6cbbf37782c247d14984e1015a109431e4180d76af6 languageName: node linkType: hard @@ -1299,18 +1269,19 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:8.34.1": - version: 8.34.1 - resolution: "@typescript-eslint/type-utils@npm:8.34.1" +"@typescript-eslint/type-utils@npm:8.41.0": + version: 8.41.0 + resolution: "@typescript-eslint/type-utils@npm:8.41.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:8.34.1" - "@typescript-eslint/utils": "npm:8.34.1" + "@typescript-eslint/types": "npm:8.41.0" + "@typescript-eslint/typescript-estree": "npm:8.41.0" + "@typescript-eslint/utils": "npm:8.41.0" debug: "npm:^4.3.4" ts-api-utils: "npm:^2.1.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.9.0" - checksum: 10c0/502a2cdfe47f1f34206c747b5a70e0242dd99f570511db3dda9c5f999d9abadfbbb1dfa82a1fa437a1689d232715412e61c97d95f19c9314ba5ad23196b4096d + typescript: ">=4.8.4 <6.0.0" + checksum: 10c0/d4f9ae07a30f1cf331c3e3a67f8749b38f199ba5000f7a600492c27f6bec774f15c3553f293c520fb999fb88108665f2785d5261daec1445b17af14a7bb0bfac languageName: node linkType: hard @@ -1321,17 +1292,10 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/types@npm:8.34.1, @typescript-eslint/types@npm:^8.34.1": - version: 8.34.1 - resolution: "@typescript-eslint/types@npm:8.34.1" - checksum: 10c0/db1b3dce6a70b28ddb13c76fbb5983240d9395656df5f7cbd99bfd9905e39c0dab2132870f01dbc406b48739c437f7d344a879a824cedaba81b91a53110dc23a - languageName: node - linkType: hard - -"@typescript-eslint/types@npm:8.35.1, @typescript-eslint/types@npm:^8.35.1": - version: 8.35.1 - resolution: "@typescript-eslint/types@npm:8.35.1" - checksum: 10c0/136dd1c7a39685baa398406423a97a4b6a66e6aed7cbd6ae698a89b0fde92c76f1415294bec612791d67d7917fda280caa65b9d761e2744e8143506d1f417fb2 +"@typescript-eslint/types@npm:8.41.0, @typescript-eslint/types@npm:^8.34.1, @typescript-eslint/types@npm:^8.41.0": + version: 8.41.0 + resolution: "@typescript-eslint/types@npm:8.41.0" + checksum: 10c0/4945a7ed7789e0527833ee378b962416d6d0d61eb6c891fe49cb6c8dc8a9adbfc58676080ca767a1f034f74f9a981caf5f4d4706cba5025c0520a801fb45d7e1 languageName: node linkType: hard @@ -1353,34 +1317,14 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:8.34.1": - version: 8.34.1 - resolution: "@typescript-eslint/typescript-estree@npm:8.34.1" - dependencies: - "@typescript-eslint/project-service": "npm:8.34.1" - "@typescript-eslint/tsconfig-utils": "npm:8.34.1" - "@typescript-eslint/types": "npm:8.34.1" - "@typescript-eslint/visitor-keys": "npm:8.34.1" - debug: "npm:^4.3.4" - fast-glob: "npm:^3.3.2" - is-glob: "npm:^4.0.3" - minimatch: "npm:^9.0.4" - semver: "npm:^7.6.0" - ts-api-utils: "npm:^2.1.0" - peerDependencies: - typescript: ">=4.8.4 <5.9.0" - checksum: 10c0/4ee7249db91b9840361f34f80b7b6d646a3af159c7298d79a33d8a11c98792fd3a395343e5e17e0fa29529e8f0113bac8baadcef90d1e140bd736a48f0485042 - languageName: node - linkType: hard - -"@typescript-eslint/typescript-estree@npm:8.35.1": - version: 8.35.1 - resolution: "@typescript-eslint/typescript-estree@npm:8.35.1" +"@typescript-eslint/typescript-estree@npm:8.41.0": + version: 8.41.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.41.0" dependencies: - "@typescript-eslint/project-service": "npm:8.35.1" - "@typescript-eslint/tsconfig-utils": "npm:8.35.1" - "@typescript-eslint/types": "npm:8.35.1" - "@typescript-eslint/visitor-keys": "npm:8.35.1" + "@typescript-eslint/project-service": "npm:8.41.0" + "@typescript-eslint/tsconfig-utils": "npm:8.41.0" + "@typescript-eslint/types": "npm:8.41.0" + "@typescript-eslint/visitor-keys": "npm:8.41.0" debug: "npm:^4.3.4" fast-glob: "npm:^3.3.2" is-glob: "npm:^4.0.3" @@ -1388,8 +1332,8 @@ __metadata: semver: "npm:^7.6.0" ts-api-utils: "npm:^2.1.0" peerDependencies: - typescript: ">=4.8.4 <5.9.0" - checksum: 10c0/6ef093cf9d7a54a323b3d112c78309b2c24c0f94e2c5b61401db9390eb7ffa3ab1da066c497907d58f0bba6986984ac73a478febd91f0bf11598108cc49f6e02 + typescript: ">=4.8.4 <6.0.0" + checksum: 10c0/e86233d895403ec4986ced25f56898b2704a84545bb7dfe933f5c64f2ab969dcb7ada7e21ea7e015c875cc94a0767e70573442724960c631b7b3fc556a984c9c languageName: node linkType: hard @@ -1411,33 +1355,18 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/utils@npm:8.34.1": - version: 8.34.1 - resolution: "@typescript-eslint/utils@npm:8.34.1" - dependencies: - "@eslint-community/eslint-utils": "npm:^4.7.0" - "@typescript-eslint/scope-manager": "npm:8.34.1" - "@typescript-eslint/types": "npm:8.34.1" - "@typescript-eslint/typescript-estree": "npm:8.34.1" - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.9.0" - checksum: 10c0/e3085877f7940c02a37653e6bc52ac6cde115e755b1f788fe4331202f371b3421cc4d0878c7d3eb054e14e9b3a064496a707a73eac471cb2b73593b9e9d4b998 - languageName: node - linkType: hard - -"@typescript-eslint/utils@npm:^8.34.1": - version: 8.35.1 - resolution: "@typescript-eslint/utils@npm:8.35.1" +"@typescript-eslint/utils@npm:8.41.0, @typescript-eslint/utils@npm:^8.34.1": + version: 8.41.0 + resolution: "@typescript-eslint/utils@npm:8.41.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.7.0" - "@typescript-eslint/scope-manager": "npm:8.35.1" - "@typescript-eslint/types": "npm:8.35.1" - "@typescript-eslint/typescript-estree": "npm:8.35.1" + "@typescript-eslint/scope-manager": "npm:8.41.0" + "@typescript-eslint/types": "npm:8.41.0" + "@typescript-eslint/typescript-estree": "npm:8.41.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.9.0" - checksum: 10c0/1fa4877caae48961d160b88fc974bb7bfe355ca2f8f6915987427354ca23621698041678adab5964caf9ad62c17b349110136890688f13b10ab1aaad74ae63d9 + typescript: ">=4.8.4 <6.0.0" + checksum: 10c0/3a2ed9b5f801afeccde44dbacdeae0b9c82cc3e1af5e92926929ad86384dc0fb0027152e68c5edfabe904647c2160c0c45ec9c848a8d67c3efb86b78a1343acb languageName: node linkType: hard @@ -1451,23 +1380,13 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:8.34.1": - version: 8.34.1 - resolution: "@typescript-eslint/visitor-keys@npm:8.34.1" - dependencies: - "@typescript-eslint/types": "npm:8.34.1" - eslint-visitor-keys: "npm:^4.2.1" - checksum: 10c0/0e5a9b3d93905d16d3cf8cb5fb346dcc6f760482eb7d0ac209aefc09a32f78ef28a687634df6ad08e81fb3e1083e8805f34472de6bbc501c0105ad654d518f40 - languageName: node - linkType: hard - -"@typescript-eslint/visitor-keys@npm:8.35.1": - version: 8.35.1 - resolution: "@typescript-eslint/visitor-keys@npm:8.35.1" +"@typescript-eslint/visitor-keys@npm:8.41.0": + version: 8.41.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.41.0" dependencies: - "@typescript-eslint/types": "npm:8.35.1" + "@typescript-eslint/types": "npm:8.41.0" eslint-visitor-keys: "npm:^4.2.1" - checksum: 10c0/55b9eb15842a5d5dca11375e436340c731e01b07190c741d2656330f3e4d88b59e1bf3d677681dd091460be2b6e5f2c42e92faea36f947d25382ead5e8118108 + checksum: 10c0/cfe52e77b9e07c23a4d9f4adf9e6bf27822e58694c9a34fefa4b9fc96d553e9df561971c4da5fc78392522e34696fc1149a76f6a02c328136771c5efe0fd1029 languageName: node linkType: hard @@ -1499,14 +1418,15 @@ __metadata: linkType: hard "@wdio/logger@npm:^9.0.0": - version: 9.15.0 - resolution: "@wdio/logger@npm:9.15.0" + version: 9.18.0 + resolution: "@wdio/logger@npm:9.18.0" dependencies: chalk: "npm:^5.1.2" loglevel: "npm:^1.6.0" loglevel-plugin-prefix: "npm:^0.8.4" + safe-regex2: "npm:^5.0.0" strip-ansi: "npm:^7.1.0" - checksum: 10c0/24f66b97c7a9ac6d9969be18ba0a5d862e31dbfd09b566229927827fd2481a856c1fb7a3a69b675a26706e1d4ae322b7230abb88fb7b3987c901549ed5f1464c + checksum: 10c0/c11cc06ea9f6696a0077f29d0360c10828317e5980815408d04cad99db1a64a6bc1491583ffef681e46e18476f061f37a2e18706f06488715291f3bfc8b32615 languageName: node linkType: hard @@ -1566,9 +1486,9 @@ __metadata: linkType: hard "@xmldom/xmldom@npm:^0.8.8": - version: 0.8.10 - resolution: "@xmldom/xmldom@npm:0.8.10" - checksum: 10c0/c7647c442502720182b0d65b17d45d2d95317c1c8c497626fe524bda79b4fb768a9aa4fae2da919f308e7abcff7d67c058b102a9d641097e9a57f0b80187851f + version: 0.8.11 + resolution: "@xmldom/xmldom@npm:0.8.11" + checksum: 10c0/e768623de72c95d3dae6b5da8e33dda0d81665047811b5498d23a328d45b13feb5536fe921d0308b96a4a8dd8addf80b1f6ef466508051c0b581e63e0dc74ed5 languageName: node linkType: hard @@ -1580,9 +1500,9 @@ __metadata: linkType: hard "@zip.js/zip.js@npm:^2.7.48": - version: 2.7.62 - resolution: "@zip.js/zip.js@npm:2.7.62" - checksum: 10c0/269da31f7514ccbdd8766f0b0c440edb7df53add731862c97f3b27b594182466ce62a03fa4be5ed736a5ac0cd1c5ead09d35c97e27887c8c6f6bfd477102ea8f + version: 2.7.72 + resolution: "@zip.js/zip.js@npm:2.7.72" + checksum: 10c0/26def4367ff242a7203228a74722585f13da4ff1466ace65170f15e77ea956e8d2a9115b917cf8683cb0551c96df716a2489f4e81a557a60f48d28332a480c15 languageName: node linkType: hard @@ -1663,9 +1583,9 @@ __metadata: linkType: hard "agent-base@npm:^7.0.2, agent-base@npm:^7.1.0, agent-base@npm:^7.1.2": - version: 7.1.3 - resolution: "agent-base@npm:7.1.3" - checksum: 10c0/6192b580c5b1d8fb399b9c62bf8343d76654c2dd62afcb9a52b2cf44a8b6ace1e3b704d3fe3547d91555c857d3df02603341ff2cb961b9cfe2b12f9f3c38ee11 + version: 7.1.4 + resolution: "agent-base@npm:7.1.4" + checksum: 10c0/c2c9ab7599692d594b6a161559ada307b7a624fa4c7b03e3afdb5a5e31cd0e53269115b620fcab024c5ac6a6f37fa5eb2e004f076ad30f5f7e6b8b671f7b35fe languageName: node linkType: hard @@ -1718,36 +1638,36 @@ __metadata: linkType: hard "allure-commandline@npm:^2.34.0": - version: 2.34.0 - resolution: "allure-commandline@npm:2.34.0" + version: 2.34.1 + resolution: "allure-commandline@npm:2.34.1" bin: allure: bin/allure - checksum: 10c0/73041dd607f2a39ecb458645173b4e74ce12895d8ec4531b925de1f9781bf0b518f5a21f84601aef11d9bd52b5758b988df0a94ea7081f4c73d9b81fccd8e2e0 + checksum: 10c0/8f8d67e0c917d83b2324d760ea8d082c4c8527dcf3feb5b0a1fd4a13cfc995314d447b1084b25b651d68f5fb75d1b1157b0d55bbdc58d23e5e26ea38741df1a4 languageName: node linkType: hard -"allure-js-commons@npm:3.2.2": - version: 3.2.2 - resolution: "allure-js-commons@npm:3.2.2" +"allure-js-commons@npm:3.3.3": + version: 3.3.3 + resolution: "allure-js-commons@npm:3.3.3" dependencies: md5: "npm:^2.3.0" peerDependencies: - allure-playwright: 3.2.2 + allure-playwright: 3.3.3 peerDependenciesMeta: allure-playwright: optional: true - checksum: 10c0/bc56d959ae8bd299566ef63f0430af5ebc7188e3d6525b805c677ff366c5dbd426f2cea37e61d26aceae07579388a3e2ba4450328b633bd99526fc4cc9818f00 + checksum: 10c0/a5b570dba648c23c88b2da4252a3f5e288f135cf12b57cc1ab244233cfeb0dc1ceb75037203b69157935118c37a3f88f2c012049c216fb0fe980ce3f5e3d6c22 languageName: node linkType: hard "allure-playwright@npm:^3.2.2": - version: 3.2.2 - resolution: "allure-playwright@npm:3.2.2" + version: 3.3.3 + resolution: "allure-playwright@npm:3.3.3" dependencies: - allure-js-commons: "npm:3.2.2" + allure-js-commons: "npm:3.3.3" peerDependencies: "@playwright/test": ">=1.36.0" - checksum: 10c0/6a32165487101ab81c57713cbfc64dcf6f7605fd048b113a371ae3f32a1b34ab1e26e76316011db28b2216143598d53b0fa6c283ebc33118dff98a2b0830fa45 + checksum: 10c0/0e7de2c20c92508cebd1b58246205d7fdc2ff53d0ccd537d7814c1affd38fdc6b853eace1e125ba73a74d79528c7a1a242073f41a0b19e9e2defa60afa5fb496 languageName: node linkType: hard @@ -1759,9 +1679,9 @@ __metadata: linkType: hard "ansi-regex@npm:^6.0.1": - version: 6.1.0 - resolution: "ansi-regex@npm:6.1.0" - checksum: 10c0/a91daeddd54746338478eef88af3439a7edf30f8e23196e2d6ed182da9add559c601266dbef01c2efa46a958ad6f1f8b176799657616c702b5b02e799e7fd8dc + version: 6.2.0 + resolution: "ansi-regex@npm:6.2.0" + checksum: 10c0/20a2e55ae9816074a60e6729dbe3daad664cd967fc82acc08b02f5677db84baa688babf940d71f50acbbb184c02459453789705e079f4d521166ae66451de551 languageName: node linkType: hard @@ -1782,8 +1702,8 @@ __metadata: linkType: hard "appium-adb@npm:^12.0.0, appium-adb@npm:^12.12.0, appium-adb@npm:^12.7.0": - version: 12.12.5 - resolution: "appium-adb@npm:12.12.5" + version: 12.13.1 + resolution: "appium-adb@npm:12.13.1" dependencies: "@appium/support": "npm:^6.0.0" async-lock: "npm:^1.0.0" @@ -1795,7 +1715,7 @@ __metadata: semver: "npm:^7.0.0" source-map-support: "npm:^0.x" teen_process: "npm:^2.2.0" - checksum: 10c0/1cf51510e0ba2ff6e58eb441d6cc38c14f04f60eb1cd660bca045e4b9a53eae446a7068feb1c03b6ed57b99fbd375bba1cf4f1f17b8375257b1df3355eb5c1ec + checksum: 10c0/1de6a60e79b2e4959dd7d48ddeb78a54e2967bb228d5b518d6b8fa6558dcd6ba13b61db323d60b6c5f2e1f4ec15cd1bced4c778e704808aa61c5bb57ef2fa5ed languageName: node linkType: hard @@ -1828,8 +1748,8 @@ __metadata: linkType: hard "appium-chromedriver@npm:^7.0.0": - version: 7.0.27 - resolution: "appium-chromedriver@npm:7.0.27" + version: 7.0.35 + resolution: "appium-chromedriver@npm:7.0.35" dependencies: "@appium/base-driver": "npm:^9.1.0" "@appium/support": "npm:^6.0.0" @@ -1844,7 +1764,7 @@ __metadata: source-map-support: "npm:^0.x" teen_process: "npm:^2.2.0" xpath: "npm:^0.x" - checksum: 10c0/5aadfbe716ec656a24417706d9661568cb45702c04cdd1c65cc79e904ec475bfb7fcc14be0d5a40e6d5587fc0a07dd967e841bc01a9ec1491574f0c110e227c6 + checksum: 10c0/83c319571910897fdf3481c31a95215c97827e62ca6c9d3f7a50f3285bd7e4af6841020f5b9e68c9573990ff1f1cfc905a573942fa338cc1628b430065d51d9e languageName: node linkType: hard @@ -1863,8 +1783,8 @@ __metadata: linkType: hard "appium-ios-device@npm:^2.0.0, appium-ios-device@npm:^2.7.25, appium-ios-device@npm:^2.8.0": - version: 2.8.4 - resolution: "appium-ios-device@npm:2.8.4" + version: 2.9.0 + resolution: "appium-ios-device@npm:2.9.0" dependencies: "@appium/support": "npm:^6.0.0" asyncbox: "npm:^3.0.0" @@ -1876,7 +1796,7 @@ __metadata: semver: "npm:^7.0.0" source-map-support: "npm:^0.x" uuid: "npm:^11.0.1" - checksum: 10c0/313cb57d22f672f875ba8786627cc5df685af3972e21cdbbef74a351f76f12a053dfa6043bccb2402f8676ed52fed39795863c60a7950d7f32b7c73d620a2534 + checksum: 10c0/b501d058c96c2c39db6060cb3f277ad2e1333c88f9dd90dac2904eaaa7b655e681169bd46b7530b3e5520148f9fe1e0e536bb11427284f78aae8208a71616386 languageName: node linkType: hard @@ -1900,8 +1820,8 @@ __metadata: linkType: hard "appium-remote-debugger@npm:^12.1.1": - version: 12.2.5 - resolution: "appium-remote-debugger@npm:12.2.5" + version: 12.2.10 + resolution: "appium-remote-debugger@npm:12.2.10" dependencies: "@appium/base-driver": "npm:^9.0.0" "@appium/support": "npm:^6.0.0" @@ -1912,7 +1832,7 @@ __metadata: lodash: "npm:^4.17.11" source-map-support: "npm:^0.x" teen_process: "npm:^2.0.0" - checksum: 10c0/7fb5955a5f2598785908b3b208aaa29e2a82e1a843c46477d913a442e8af29239c9f24c86625e61fe4d8e6d925f7a255e70240d48eda212c69ab1c1d6846dc1a + checksum: 10c0/ef4bab173e131517c4f7b09ea99acf76c156fa1a09dc4ed2d6e62ae045a1b90cdf6d5a4b456cd3bcd2b822c6b45b0248b2d7a5b615f6338f3a09738a4e5df468 languageName: node linkType: hard @@ -1963,9 +1883,9 @@ __metadata: linkType: hard "appium-uiautomator2-server@npm:^7.0.24": - version: 7.6.2 - resolution: "appium-uiautomator2-server@npm:7.6.2" - checksum: 10c0/cd4c46c49cae9e0095d7db318f39cb4ad111322bbe8d91aae3b58d620864844c10ca7e19e2f54c06063ca3e0c4fcc9de873666f8ec4f6f75ecdd0365de9aa521 + version: 7.7.1 + resolution: "appium-uiautomator2-server@npm:7.7.1" + checksum: 10c0/312998f84d1c0550e47f02ccf56e6c7693c4d24d18258f2459ec3e14911de17c7f4051fc4896d4b43bdc23a5dfcf4ff997644ad6997008ce8bf0dc56891eb2b9 languageName: node linkType: hard @@ -2292,13 +2212,13 @@ __metadata: linkType: hard "axios@npm:^1.4.0, axios@npm:^1.6.5, axios@npm:^1.6.7, axios@npm:^1.x": - version: 1.10.0 - resolution: "axios@npm:1.10.0" + version: 1.11.0 + resolution: "axios@npm:1.11.0" dependencies: follow-redirects: "npm:^1.15.6" - form-data: "npm:^4.0.0" + form-data: "npm:^4.0.4" proxy-from-env: "npm:^1.1.0" - checksum: 10c0/2239cb269cc789eac22f5d1aabd58e1a83f8f364c92c2caa97b6f5cbb4ab2903d2e557d9dc670b5813e9bcdebfb149e783fb8ab3e45098635cd2f559b06bd5d8 + checksum: 10c0/5de273d33d43058610e4d252f0963cc4f10714da0bfe872e8ef2cbc23c2c999acc300fd357b6bce0fc84a2ca9bd45740fa6bb28199ce2c1266c8b1a393f2b36e languageName: node linkType: hard @@ -2317,15 +2237,15 @@ __metadata: linkType: hard "bare-events@npm:^2.2.0, bare-events@npm:^2.5.4": - version: 2.5.4 - resolution: "bare-events@npm:2.5.4" - checksum: 10c0/877a9cea73d545e2588cdbd6fd01653e27dac48ad6b44985cdbae73e1f57f292d4ba52e25d1fba53674c1053c463d159f3d5c7bc36a2e6e192e389b499ddd627 + version: 2.6.1 + resolution: "bare-events@npm:2.6.1" + checksum: 10c0/948aabf7380120445f7f7b01bd3911c28ad72a8eaa08f6e308bd470b303593d3639309d1a4e5e5c1ab99503a45a18152f474f065be3698bfe68a27ca21f64e37 languageName: node linkType: hard "bare-fs@npm:^4.0.1": - version: 4.1.5 - resolution: "bare-fs@npm:4.1.5" + version: 4.2.1 + resolution: "bare-fs@npm:4.2.1" dependencies: bare-events: "npm:^2.5.4" bare-path: "npm:^3.0.0" @@ -2335,14 +2255,14 @@ __metadata: peerDependenciesMeta: bare-buffer: optional: true - checksum: 10c0/af72ec30bb7844524faa14ae2b74d13b08920b1d839c638da4ad1abdda643958d0b86653d284878a2f9160072b603c9dce55c8cc29da8d84e14ffce1c5d42a01 + checksum: 10c0/16cb6593b69d277bceb03710533682e8677dd8598ebc757cf406faa1f6178446f534726d845519fc77469ad8d86265e8c9f5b419fd93a8c7e30aacc1722ee05d languageName: node linkType: hard "bare-os@npm:^3.0.1": - version: 3.6.1 - resolution: "bare-os@npm:3.6.1" - checksum: 10c0/13064789b3d0d3051d6a89424e6d861c08be101798d69faa78821cffb428b36d1fd4e17c824d5a4939bcd96dbff42c11921494139c8e53c3e520bc0e3f83aeee + version: 3.6.2 + resolution: "bare-os@npm:3.6.2" + checksum: 10c0/7d917bc202b7efbb6b78658403fac04ae4e91db98d38cbd24037f896a2b1b4f4571d8cd408d12bed6a4c406d6abaf8d03836eacbcc4c75a0b6974e268574fc5a languageName: node linkType: hard @@ -2356,8 +2276,8 @@ __metadata: linkType: hard "bare-stream@npm:^2.6.4": - version: 2.6.5 - resolution: "bare-stream@npm:2.6.5" + version: 2.7.0 + resolution: "bare-stream@npm:2.7.0" dependencies: streamx: "npm:^2.21.0" peerDependencies: @@ -2368,7 +2288,7 @@ __metadata: optional: true bare-events: optional: true - checksum: 10c0/1242286f8f3147e9fd353cdaa9cf53226a807ac0dde8177c13f1463aa4cd1f88e07407c883a1b322b901e9af2d1cd30aacd873529031132c384622972e0419df + checksum: 10c0/3acd840b7b288dc066226c36446ff605fba2ecce98f1a0ce6aa611b81aabbcd204046a3209bce172373d17eaeaa5b7d35a85649c18ffcb9f2c783242854e99bd languageName: node linkType: hard @@ -2657,9 +2577,9 @@ __metadata: linkType: hard "chalk@npm:^5.1.2": - version: 5.4.1 - resolution: "chalk@npm:5.4.1" - checksum: 10c0/b23e88132c702f4855ca6d25cb5538b1114343e41472d5263ee8a37cccfccd9c4216d111e1097c6a27830407a1dc81fecdf2a56f2c63033d4dbbd88c10b0dcef + version: 5.6.0 + resolution: "chalk@npm:5.6.0" + checksum: 10c0/f8558fc12fd9805f167611803b325b0098bbccdc9f1d3bafead41c9bac61f263357f3c0df0cbe28bc2fd5fca3edcf618b01d6771a5a776b4c15d061482a72b23 languageName: node linkType: hard @@ -3039,9 +2959,9 @@ __metadata: linkType: hard "css-selector-parser@npm:^3.0.0": - version: 3.1.2 - resolution: "css-selector-parser@npm:3.1.2" - checksum: 10c0/4164e68a3684a834feda10665bc85b107c7fd64625c055dca1eab403169bf531cde3425ac4b869633fe536677a90debb5bc85511ff8f464e3acb8f5cb57c3169 + version: 3.1.3 + resolution: "css-selector-parser@npm:3.1.3" + checksum: 10c0/0bba96edfd27827d79933b113c42bec627b96a79f6fe4b12dec12da109d0b3a25f2f76d385b7c28ff22dca68840251751d1061d9226657755430e4787bf4594e languageName: node linkType: hard @@ -3134,9 +3054,9 @@ __metadata: linkType: hard "decamelize@npm:^6.0.0": - version: 6.0.0 - resolution: "decamelize@npm:6.0.0" - checksum: 10c0/689888f5ea39add843d79fb5a8d3bc1ce1df7583899bc7cef081c3deecd54758e24e8692f4c214e0ea6917742bb05ea1991e3e15c33031e7aa7b9041e8e8033a + version: 6.0.1 + resolution: "decamelize@npm:6.0.1" + checksum: 10c0/c0a3a529591ebab1d1a9458b60684194e91d904e9b0a56367d3d507b2c8ab89dfd40c61423ca6a1eb2f70e2d44d2efe78f3342326395d3738d1d42592b1a6224 languageName: node linkType: hard @@ -3277,9 +3197,9 @@ __metadata: linkType: hard "dotenv@npm:^16.4.5": - version: 16.5.0 - resolution: "dotenv@npm:16.5.0" - checksum: 10c0/5bc94c919fbd955bf0ba44d33922a1e93d1078e64a1db5c30faeded1d996e7a83c55332cb8ea4fae5a9ca4d0be44cbceb95c5811e70f9f095298df09d1997dd9 + version: 16.6.1 + resolution: "dotenv@npm:16.6.1" + checksum: 10c0/15ce56608326ea0d1d9414a5c8ee6dcf0fffc79d2c16422b4ac2268e7e2d76ff5a572d37ffe747c377de12005f14b3cc22361e79fc7f1061cce81f77d2c973dc languageName: node linkType: hard @@ -3571,17 +3491,17 @@ __metadata: linkType: hard "eslint@npm:^9.14.0": - version: 9.29.0 - resolution: "eslint@npm:9.29.0" + version: 9.34.0 + resolution: "eslint@npm:9.34.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.2.0" "@eslint-community/regexpp": "npm:^4.12.1" - "@eslint/config-array": "npm:^0.20.1" - "@eslint/config-helpers": "npm:^0.2.1" - "@eslint/core": "npm:^0.14.0" + "@eslint/config-array": "npm:^0.21.0" + "@eslint/config-helpers": "npm:^0.3.1" + "@eslint/core": "npm:^0.15.2" "@eslint/eslintrc": "npm:^3.3.1" - "@eslint/js": "npm:9.29.0" - "@eslint/plugin-kit": "npm:^0.3.1" + "@eslint/js": "npm:9.34.0" + "@eslint/plugin-kit": "npm:^0.3.5" "@humanfs/node": "npm:^0.16.6" "@humanwhocodes/module-importer": "npm:^1.0.1" "@humanwhocodes/retry": "npm:^0.4.2" @@ -3616,7 +3536,7 @@ __metadata: optional: true bin: eslint: bin/eslint.js - checksum: 10c0/75e3f841e0f8b0fa93dbb2ba6ae538bd8b611c3654117bc3dadf90bb009923dfd2c15ec2948dc6e6b8b571317cc125c5cceb9255da8cd644ee740020df645dd8 + checksum: 10c0/ba3e54fa0c8ed23d062f91519afaae77fed922a6c4d76130b6cd32154bcb406aaea4b3c5ed88e0be40828c1d5b6921592f3947dbdc5e2043de6bd7aa341fe5ea languageName: node linkType: hard @@ -3834,9 +3754,9 @@ __metadata: linkType: hard "fast-uri@npm:^3.0.1": - version: 3.0.6 - resolution: "fast-uri@npm:3.0.6" - checksum: 10c0/74a513c2af0584448aee71ce56005185f81239eab7a2343110e5bad50c39ad4fb19c5a6f99783ead1cac7ccaf3461a6034fda89fffa2b30b6d99b9f21c2f9d29 + version: 3.1.0 + resolution: "fast-uri@npm:3.1.0" + checksum: 10c0/44364adca566f70f40d1e9b772c923138d47efeac2ae9732a872baafd77061f26b097ba2f68f0892885ad177becd065520412b8ffeec34b16c99433c5b9e2de7 languageName: node linkType: hard @@ -3877,14 +3797,14 @@ __metadata: linkType: hard "fdir@npm:^6.4.4": - version: 6.4.6 - resolution: "fdir@npm:6.4.6" + version: 6.5.0 + resolution: "fdir@npm:6.5.0" peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: picomatch: optional: true - checksum: 10c0/45b559cff889934ebb8bc498351e5acba40750ada7e7d6bde197768d2fa67c149be8ae7f8ff34d03f4e1eb20f2764116e56440aaa2f6689e9a4aa7ef06acafe9 + checksum: 10c0/e345083c4306b3aed6cb8ec551e26c36bab5c511e99ea4576a16750ddc8d3240e63826cc624f5ae17ad4dc82e68a253213b60d556c11bfad064b7607847ed07f languageName: node linkType: hard @@ -4012,12 +3932,12 @@ __metadata: linkType: hard "follow-redirects@npm:^1.15.6": - version: 1.15.9 - resolution: "follow-redirects@npm:1.15.9" + version: 1.15.11 + resolution: "follow-redirects@npm:1.15.11" peerDependenciesMeta: debug: optional: true - checksum: 10c0/5829165bd112c3c0e82be6c15b1a58fa9dcfaede3b3c54697a82fe4a62dd5ae5e8222956b448d2f98e331525f05d00404aba7d696de9e761ef6e42fdc780244f + checksum: 10c0/d301f430542520a54058d4aeeb453233c564aaccac835d29d15e050beb33f339ad67d9bddbce01739c5dc46a6716dbe3d9d0d5134b1ca203effa11a7ef092343 languageName: node linkType: hard @@ -4057,16 +3977,16 @@ __metadata: languageName: node linkType: hard -"form-data@npm:^4.0.0": - version: 4.0.3 - resolution: "form-data@npm:4.0.3" +"form-data@npm:^4.0.0, form-data@npm:^4.0.4": + version: 4.0.4 + resolution: "form-data@npm:4.0.4" dependencies: asynckit: "npm:^0.4.0" combined-stream: "npm:^1.0.8" es-set-tostringtag: "npm:^2.1.0" hasown: "npm:^2.0.2" mime-types: "npm:^2.1.12" - checksum: 10c0/f0cf45873d600110b5fadf5804478377694f73a1ed97aaa370a74c90cebd7fe6e845a081171668a5476477d0d55a73a4e03d6682968fa8661eac2a81d651fcdb + checksum: 10c0/373525a9a034b9d57073e55eab79e501a714ffac02e7a9b01be1c820780652b16e4101819785e1e18f8d98f0aee866cc654d660a435c378e16a72f2e7cac9695 languageName: node linkType: hard @@ -4112,13 +4032,13 @@ __metadata: linkType: hard "fs-extra@npm:^11.1.1, fs-extra@npm:^11.3.0": - version: 11.3.0 - resolution: "fs-extra@npm:11.3.0" + version: 11.3.1 + resolution: "fs-extra@npm:11.3.1" dependencies: graceful-fs: "npm:^4.2.0" jsonfile: "npm:^6.0.1" universalify: "npm:^2.0.0" - checksum: 10c0/5f95e996186ff45463059feb115a22fb048bdaf7e487ecee8a8646c78ed8fdca63630e3077d4c16ce677051f5e60d3355a06f3cd61f3ca43f48cc58822a44d0a + checksum: 10c0/61e5b7285b1ca72c68dfe1058b2514294a922683afac2a80aa90540f9bd85370763d675e3b408ef500077d355956fece3bd24b546790e261c3d3015967e2b2d9 languageName: node linkType: hard @@ -4310,13 +4230,13 @@ __metadata: linkType: hard "get-uri@npm:^6.0.1": - version: 6.0.4 - resolution: "get-uri@npm:6.0.4" + version: 6.0.5 + resolution: "get-uri@npm:6.0.5" dependencies: basic-ftp: "npm:^5.0.2" data-uri-to-buffer: "npm:^6.0.2" debug: "npm:^4.3.4" - checksum: 10c0/07c87abe1f97a4545fae329a37a45e276ec57e6ad48dad2a97780f87c96b00a82c2043ab49e1a991f99bb5cff8f8ed975e44e4f8b3c9600f35493a97f123499f + checksum: 10c0/c7ff5d5d55de53d23ecce7c5108cc3ed0db1174db43c9aa15506d640283d36ee0956fd8ba1fc50b06a718466cc85794ae9d8860193f91318afe846e3e7010f3a languageName: node linkType: hard @@ -4768,8 +4688,8 @@ __metadata: linkType: hard "io.appium.settings@npm:^5.12.11, io.appium.settings@npm:^5.12.22": - version: 5.14.12 - resolution: "io.appium.settings@npm:5.14.12" + version: 5.14.15 + resolution: "io.appium.settings@npm:5.14.15" dependencies: "@appium/logger": "npm:^1.3.0" asyncbox: "npm:^3.0.0" @@ -4778,17 +4698,14 @@ __metadata: semver: "npm:^7.5.4" source-map-support: "npm:^0.x" teen_process: "npm:^2.0.0" - checksum: 10c0/2d393a5c34ab9edeb33b96c86edd9151cd7fbc73b3b816e1535549017555781b10a663231a76f5a450bf31aad32d9d21683df88cc0b459898a89a25a187208f2 + checksum: 10c0/428afdf404d7297475646fee5afa217dc5fb3e9b347080eefded372d54517321aaa0137435ab54666d0e42a0232f00187113b08ca828670022b6b1eb190b7668 languageName: node linkType: hard -"ip-address@npm:^9.0.5": - version: 9.0.5 - resolution: "ip-address@npm:9.0.5" - dependencies: - jsbn: "npm:1.1.0" - sprintf-js: "npm:^1.1.3" - checksum: 10c0/331cd07fafcb3b24100613e4b53e1a2b4feab11e671e655d46dc09ee233da5011284d09ca40c4ecbdfe1d0004f462958675c224a804259f2f78d2465a87824bc +"ip-address@npm:^10.0.1": + version: 10.0.1 + resolution: "ip-address@npm:10.0.1" + checksum: 10c0/1634d79dae18394004775cb6d699dc46b7c23df6d2083164025a2b15240c1164fccde53d0e08bd5ee4fc53913d033ab6b5e395a809ad4b956a940c446e948843 languageName: node linkType: hard @@ -5001,13 +4918,6 @@ __metadata: languageName: node linkType: hard -"jsbn@npm:1.1.0": - version: 1.1.0 - resolution: "jsbn@npm:1.1.0" - checksum: 10c0/4f907fb78d7b712e11dea8c165fe0921f81a657d3443dde75359ed52eb2b5d33ce6773d97985a089f09a65edd80b11cb75c767b57ba47391fee4c969f7215c96 - languageName: node - linkType: hard - "jsbn@npm:~0.1.0": version: 0.1.1 resolution: "jsbn@npm:0.1.1" @@ -5100,15 +5010,15 @@ __metadata: linkType: hard "jsonfile@npm:^6.0.1": - version: 6.1.0 - resolution: "jsonfile@npm:6.1.0" + version: 6.2.0 + resolution: "jsonfile@npm:6.2.0" dependencies: graceful-fs: "npm:^4.1.6" universalify: "npm:^2.0.0" dependenciesMeta: graceful-fs: optional: true - checksum: 10c0/4f95b5e8a5622b1e9e8f33c96b7ef3158122f595998114d1e7f03985649ea99cb3cd99ce1ed1831ae94c8c8543ab45ebd044207612f31a56fd08462140e46865 + checksum: 10c0/7f4f43b08d1869ded8a6822213d13ae3b99d651151d77efd1557ced0889c466296a7d9684e397bd126acf5eb2cfcb605808c3e681d0fdccd2fe5a04b47e76c0d languageName: node linkType: hard @@ -5304,7 +5214,7 @@ __metadata: languageName: node linkType: hard -"lodash.get@npm:^4, lodash.get@npm:^4.4.2": +"lodash.get@npm:^4": version: 4.4.2 resolution: "lodash.get@npm:4.4.2" checksum: 10c0/48f40d471a1654397ed41685495acb31498d5ed696185ac8973daef424a749ca0c7871bf7b665d5c14f5cc479394479e0307e781f61d5573831769593411be6e @@ -6010,8 +5920,8 @@ __metadata: linkType: hard "node-gyp@npm:latest": - version: 11.2.0 - resolution: "node-gyp@npm:11.2.0" + version: 11.4.2 + resolution: "node-gyp@npm:11.4.2" dependencies: env-paths: "npm:^2.2.0" exponential-backoff: "npm:^3.1.1" @@ -6025,7 +5935,7 @@ __metadata: which: "npm:^5.0.0" bin: node-gyp: bin/node-gyp.js - checksum: 10c0/bd8d8c76b06be761239b0c8680f655f6a6e90b48e44d43415b11c16f7e8c15be346fba0cbf71588c7cdfb52c419d928a7d3db353afc1d952d19756237d8f10b9 + checksum: 10c0/0bfd3e96770ed70f07798d881dd37b4267708966d868a0e585986baac487d9cf5831285579fd629a83dc4e434f53e6416ce301097f2ee464cb74d377e4d8bdbe languageName: node linkType: hard @@ -6522,9 +6432,9 @@ __metadata: linkType: hard "picomatch@npm:^4.0.2": - version: 4.0.2 - resolution: "picomatch@npm:4.0.2" - checksum: 10c0/7c51f3ad2bb42c776f49ebf964c644958158be30d0a510efd5a395e8d49cb5acfed5b82c0c5b365523ce18e6ab85013c9ebe574f60305892ec3fa8eee8304ccc + version: 4.0.3 + resolution: "picomatch@npm:4.0.3" + checksum: 10c0/9582c951e95eebee5434f59e426cddd228a7b97a0161a375aed4be244bd3fe8e3a31b846808ea14ef2c8a2527a6eeab7b3946a67d5979e81694654f939473ae2 languageName: node linkType: hard @@ -6546,27 +6456,27 @@ __metadata: languageName: node linkType: hard -"playwright-core@npm:1.53.1": - version: 1.53.1 - resolution: "playwright-core@npm:1.53.1" +"playwright-core@npm:1.55.0": + version: 1.55.0 + resolution: "playwright-core@npm:1.55.0" bin: playwright-core: cli.js - checksum: 10c0/8780552740741b94c346373ab6f949e9a44d3df54016b12123da9fe2f5fb60c1838197642916789b0a2ffb567e4ba0089f2e57d496bef7e460ddc4526f9b3b0f + checksum: 10c0/c39d6aa30e7a4e73965942ca5e13405ae05c9cb49f755a35f04248c864c0b24cf662d9767f1797b3ec48d1cf4e54774dce4a19c16534bd5cfd2aa3da81c9dc3a languageName: node linkType: hard -"playwright@npm:1.53.1": - version: 1.53.1 - resolution: "playwright@npm:1.53.1" +"playwright@npm:1.55.0": + version: 1.55.0 + resolution: "playwright@npm:1.55.0" dependencies: fsevents: "npm:2.3.2" - playwright-core: "npm:1.53.1" + playwright-core: "npm:1.55.0" dependenciesMeta: fsevents: optional: true bin: playwright: cli.js - checksum: 10c0/3dcbcd3791a7f0d1007db4d3126c8136258a2002c2fbfc8b840086b64cbc1fb628b2e25dd3b345d685fb27ba39790ab0f4ce81a8faade7dc748af3a63bdf3550 + checksum: 10c0/51605b7e57a5650e57972c5fdfc09d7a9934cca1cbee5beacca716fa801e25cb5bb7c1663de90c22b300fde884e5545a2b13a0505a93270b660687791c478304 languageName: node linkType: hard @@ -6613,11 +6523,11 @@ __metadata: linkType: hard "prettier@npm:^3.3.3": - version: 3.5.3 - resolution: "prettier@npm:3.5.3" + version: 3.6.2 + resolution: "prettier@npm:3.6.2" bin: prettier: bin/prettier.cjs - checksum: 10c0/3880cb90b9dc0635819ab52ff571518c35bd7f15a6e80a2054c05dbc8a3aa6e74f135519e91197de63705bcb38388ded7e7230e2178432a1468005406238b877 + checksum: 10c0/488cb2f2b99ec13da1e50074912870217c11edaddedeadc649b1244c749d15ba94e846423d062e2c4c9ae683e2d65f754de28889ba06e697ac4f988d44f45812 languageName: node linkType: hard @@ -6998,6 +6908,13 @@ __metadata: languageName: node linkType: hard +"ret@npm:~0.5.0": + version: 0.5.0 + resolution: "ret@npm:0.5.0" + checksum: 10c0/220868b194f87bf1998e32e409086eec6b39e860c052bf267f8ad4d0131706a9773d45fd3f91acfb1a7c928fce002b694ab86fdba90bc8d4b8df68fa8645c5cc + languageName: node + linkType: hard + "retry@npm:^0.12.0": version: 0.12.0 resolution: "retry@npm:0.12.0" @@ -7100,6 +7017,15 @@ __metadata: languageName: node linkType: hard +"safe-regex2@npm:^5.0.0": + version: 5.0.0 + resolution: "safe-regex2@npm:5.0.0" + dependencies: + ret: "npm:~0.5.0" + checksum: 10c0/83d5b1b60a5a97cb71a6e615518ec4a47761b3600aba389089be59a417498185250db2368080afc2f5e91237d68809c6c634b97a2e1cc8bd56a4c7eef2eeb6cf + languageName: node + linkType: hard + "safe-stable-stringify@npm:^2.3.1": version: 2.5.0 resolution: "safe-stable-stringify@npm:2.5.0" @@ -7281,30 +7207,31 @@ __metadata: linkType: hard "sharp@npm:^0.34.1": - version: 0.34.2 - resolution: "sharp@npm:0.34.2" - dependencies: - "@img/sharp-darwin-arm64": "npm:0.34.2" - "@img/sharp-darwin-x64": "npm:0.34.2" - "@img/sharp-libvips-darwin-arm64": "npm:1.1.0" - "@img/sharp-libvips-darwin-x64": "npm:1.1.0" - "@img/sharp-libvips-linux-arm": "npm:1.1.0" - "@img/sharp-libvips-linux-arm64": "npm:1.1.0" - "@img/sharp-libvips-linux-ppc64": "npm:1.1.0" - "@img/sharp-libvips-linux-s390x": "npm:1.1.0" - "@img/sharp-libvips-linux-x64": "npm:1.1.0" - "@img/sharp-libvips-linuxmusl-arm64": "npm:1.1.0" - "@img/sharp-libvips-linuxmusl-x64": "npm:1.1.0" - "@img/sharp-linux-arm": "npm:0.34.2" - "@img/sharp-linux-arm64": "npm:0.34.2" - "@img/sharp-linux-s390x": "npm:0.34.2" - "@img/sharp-linux-x64": "npm:0.34.2" - "@img/sharp-linuxmusl-arm64": "npm:0.34.2" - "@img/sharp-linuxmusl-x64": "npm:0.34.2" - "@img/sharp-wasm32": "npm:0.34.2" - "@img/sharp-win32-arm64": "npm:0.34.2" - "@img/sharp-win32-ia32": "npm:0.34.2" - "@img/sharp-win32-x64": "npm:0.34.2" + version: 0.34.3 + resolution: "sharp@npm:0.34.3" + dependencies: + "@img/sharp-darwin-arm64": "npm:0.34.3" + "@img/sharp-darwin-x64": "npm:0.34.3" + "@img/sharp-libvips-darwin-arm64": "npm:1.2.0" + "@img/sharp-libvips-darwin-x64": "npm:1.2.0" + "@img/sharp-libvips-linux-arm": "npm:1.2.0" + "@img/sharp-libvips-linux-arm64": "npm:1.2.0" + "@img/sharp-libvips-linux-ppc64": "npm:1.2.0" + "@img/sharp-libvips-linux-s390x": "npm:1.2.0" + "@img/sharp-libvips-linux-x64": "npm:1.2.0" + "@img/sharp-libvips-linuxmusl-arm64": "npm:1.2.0" + "@img/sharp-libvips-linuxmusl-x64": "npm:1.2.0" + "@img/sharp-linux-arm": "npm:0.34.3" + "@img/sharp-linux-arm64": "npm:0.34.3" + "@img/sharp-linux-ppc64": "npm:0.34.3" + "@img/sharp-linux-s390x": "npm:0.34.3" + "@img/sharp-linux-x64": "npm:0.34.3" + "@img/sharp-linuxmusl-arm64": "npm:0.34.3" + "@img/sharp-linuxmusl-x64": "npm:0.34.3" + "@img/sharp-wasm32": "npm:0.34.3" + "@img/sharp-win32-arm64": "npm:0.34.3" + "@img/sharp-win32-ia32": "npm:0.34.3" + "@img/sharp-win32-x64": "npm:0.34.3" color: "npm:^4.2.3" detect-libc: "npm:^2.0.4" semver: "npm:^7.7.2" @@ -7335,6 +7262,8 @@ __metadata: optional: true "@img/sharp-linux-arm64": optional: true + "@img/sharp-linux-ppc64": + optional: true "@img/sharp-linux-s390x": optional: true "@img/sharp-linux-x64": @@ -7351,7 +7280,7 @@ __metadata: optional: true "@img/sharp-win32-x64": optional: true - checksum: 10c0/43967dbaaf1e1140a2f43b51d54762cc1bba01648392e355028568e4838833bf1abc2a96c09b893e6407b0c59a2c271d66e8d56a582aa6c951d476ab83a37fba + checksum: 10c0/df9e6645e3db6ed298a0ac956ba74e468c367fc038b547936fbdddc6a29fce9af40413acbef73b3716291530760f311a20e45c8983f20ee5ea69dd2f21464a2b languageName: node linkType: hard @@ -7503,12 +7432,12 @@ __metadata: linkType: hard "socks@npm:^2.8.3": - version: 2.8.5 - resolution: "socks@npm:2.8.5" + version: 2.8.7 + resolution: "socks@npm:2.8.7" dependencies: - ip-address: "npm:^9.0.5" + ip-address: "npm:^10.0.1" smart-buffer: "npm:^4.2.0" - checksum: 10c0/e427d0eb0451cfd04e20b9156ea8c0e9b5e38a8d70f21e55c30fbe4214eda37cfc25d782c63f9adc5fbdad6d062a0f127ef2cefc9a44b6fee2b9ea5d1ed10827 + checksum: 10c0/2805a43a1c4bcf9ebf6e018268d87b32b32b06fbbc1f9282573583acc155860dc361500f89c73bfbb157caa1b4ac78059eac0ef15d1811eb0ca75e0bdadbc9d2 languageName: node linkType: hard @@ -7564,9 +7493,9 @@ __metadata: linkType: hard "spdx-license-ids@npm:^3.0.0": - version: 3.0.21 - resolution: "spdx-license-ids@npm:3.0.21" - checksum: 10c0/ecb24c698d8496aa9efe23e0b1f751f8a7a89faedcdfcbfabae772b546c2db46ccde8f3bc447a238eb86bbcd4f73fea88720ef3b8394f7896381bec3d7736411 + version: 3.0.22 + resolution: "spdx-license-ids@npm:3.0.22" + checksum: 10c0/4a85e44c2ccfc06eebe63239193f526508ebec1abc7cf7bca8ee43923755636234395447c2c87f40fb672cf580a9c8e684513a676bfb2da3d38a4983684bbb38 languageName: node linkType: hard @@ -7604,13 +7533,6 @@ __metadata: languageName: node linkType: hard -"sprintf-js@npm:^1.1.3": - version: 1.1.3 - resolution: "sprintf-js@npm:1.1.3" - checksum: 10c0/09270dc4f30d479e666aee820eacd9e464215cdff53848b443964202bf4051490538e5dd1b42e1a65cf7296916ca17640aebf63dae9812749c7542ee5f288dec - languageName: node - linkType: hard - "sshpk@npm:^1.7.0": version: 1.18.0 resolution: "sshpk@npm:1.18.0" @@ -7829,8 +7751,8 @@ __metadata: linkType: hard "tar-fs@npm:^3.0.6": - version: 3.0.10 - resolution: "tar-fs@npm:3.0.10" + version: 3.1.0 + resolution: "tar-fs@npm:3.1.0" dependencies: bare-fs: "npm:^4.0.1" bare-path: "npm:^3.0.0" @@ -7841,7 +7763,7 @@ __metadata: optional: true bare-path: optional: true - checksum: 10c0/b8e8c1c3e9be6928a6252b491a58fe435ad01e3d7c62959cf7796f3f733d07a5ccece8b1ab81ea94c18167388759f33b6d59d6022103cdbb40a4c7c7879b63ab + checksum: 10c0/760309677543c03fbc253b5ef1ab4bb2ceafb554471b6cbe4930d1633f35662ec26a1414c66fa6754f5aa7e8c65003f73849242f624c322d3dcba7a8888a6915 languageName: node linkType: hard @@ -8190,20 +8112,21 @@ __metadata: linkType: hard "typescript-eslint@npm:^8.15.0": - version: 8.34.1 - resolution: "typescript-eslint@npm:8.34.1" + version: 8.41.0 + resolution: "typescript-eslint@npm:8.41.0" dependencies: - "@typescript-eslint/eslint-plugin": "npm:8.34.1" - "@typescript-eslint/parser": "npm:8.34.1" - "@typescript-eslint/utils": "npm:8.34.1" + "@typescript-eslint/eslint-plugin": "npm:8.41.0" + "@typescript-eslint/parser": "npm:8.41.0" + "@typescript-eslint/typescript-estree": "npm:8.41.0" + "@typescript-eslint/utils": "npm:8.41.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.9.0" - checksum: 10c0/6de5d2ce180d1609a8a5383557a2787f17620ebc9a4d84fba9d9240db8005cc3084a7840ebafe532fba9970fe12822ee415615041f3527334fdfc45c411d35b6 + typescript: ">=4.8.4 <6.0.0" + checksum: 10c0/e141ffaf0332053483526a31e68755fe1438f6367571f39e67e32c0e15d509e8678adab2020597720b0307360493724d8dcf60d0620611d7e1e209d7f952cfe9 languageName: node linkType: hard -"typescript@npm:5.8.3, typescript@npm:^5.6.3": +"typescript@npm:5.8.3": version: 5.8.3 resolution: "typescript@npm:5.8.3" bin: @@ -8213,7 +8136,17 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@npm%3A5.8.3#optional!builtin, typescript@patch:typescript@npm%3A^5.6.3#optional!builtin": +"typescript@npm:^5.6.3": + version: 5.9.2 + resolution: "typescript@npm:5.9.2" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 10c0/cd635d50f02d6cf98ed42de2f76289701c1ec587a363369255f01ed15aaf22be0813226bff3c53e99d971f9b540e0b3cc7583dbe05faded49b1b0bed2f638a18 + languageName: node + linkType: hard + +"typescript@patch:typescript@npm%3A5.8.3#optional!builtin": version: 5.8.3 resolution: "typescript@patch:typescript@npm%3A5.8.3#optional!builtin::version=5.8.3&hash=5adc0c" bin: @@ -8223,6 +8156,16 @@ __metadata: languageName: node linkType: hard +"typescript@patch:typescript@npm%3A^5.6.3#optional!builtin": + version: 5.9.2 + resolution: "typescript@patch:typescript@npm%3A5.9.2#optional!builtin::version=5.9.2&hash=5adc0c" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 10c0/66fc07779427a7c3fa97da0cf2e62595eaff2cea4594d45497d294bfa7cb514d164f0b6ce7a5121652cf44c0822af74e29ee579c771c405e002d1f23cf06bfde + languageName: node + linkType: hard + "unbzip2-stream@npm:1.4.3": version: 1.4.3 resolution: "unbzip2-stream@npm:1.4.3" @@ -8240,10 +8183,10 @@ __metadata: languageName: node linkType: hard -"undici-types@npm:~7.8.0": - version: 7.8.0 - resolution: "undici-types@npm:7.8.0" - checksum: 10c0/9d9d246d1dc32f318d46116efe3cfca5a72d4f16828febc1918d94e58f6ffcf39c158aa28bf5b4fc52f410446bc7858f35151367bd7a49f21746cab6497b709b +"undici-types@npm:~7.10.0": + version: 7.10.0 + resolution: "undici-types@npm:7.10.0" + checksum: 10c0/8b00ce50e235fe3cc601307f148b5e8fb427092ee3b23e8118ec0a5d7f68eca8cee468c8fc9f15cbb2cf2a3797945ebceb1cbd9732306a1d00e0a9b6afa0f635 languageName: node linkType: hard @@ -8681,7 +8624,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:8.18.2, ws@npm:^8.0.0, ws@npm:^8.13.0, ws@npm:^8.8.0": +"ws@npm:8.18.2": version: 8.18.2 resolution: "ws@npm:8.18.2" peerDependencies: @@ -8696,6 +8639,21 @@ __metadata: languageName: node linkType: hard +"ws@npm:^8.0.0, ws@npm:^8.13.0, ws@npm:^8.8.0": + version: 8.18.3 + resolution: "ws@npm:8.18.3" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 10c0/eac918213de265ef7cb3d4ca348b891a51a520d839aa51cdb8ca93d4fa7ff9f6ccb339ccee89e4075324097f0a55157c89fa3f7147bde9d8d7e90335dc087b53 + languageName: node + linkType: hard + "xmlbuilder@npm:^15.1.1": version: 15.1.1 resolution: "xmlbuilder@npm:15.1.1"