From 1c24a5889df35f1630cd071d5b4304c98b60ad52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Carden=CC=83a?= <35935591+luisecm@users.noreply.github.com> Date: Mon, 30 Oct 2023 23:42:35 -0600 Subject: [PATCH 01/22] chore(appium): use two GH runners to run chats tests on macos --- .github/workflows/ui-automated-tests.yml | 149 +++++++++++++++++- config/wdio.mac.chatA.conf.ts | 144 +++++++++++++++++ config/wdio.mac.chatB.conf.ts | 144 +++++++++++++++++ package.json | 2 + .../ChatUserA/01-create-account.spec.ts | 20 +++ .../ChatUserB/01-create-account.spec.ts | 20 +++ tests/suites/Chats/02-ChatsUserA.suite.ts | 0 tests/suites/Chats/03-ChatsUserB.suite.ts | 0 .../suites/MainTests/01-UplinkTests.suite.ts | 2 + 9 files changed, 480 insertions(+), 1 deletion(-) create mode 100644 config/wdio.mac.chatA.conf.ts create mode 100644 config/wdio.mac.chatB.conf.ts create mode 100644 tests/specs/reusable-accounts/ChatUserA/01-create-account.spec.ts create mode 100644 tests/specs/reusable-accounts/ChatUserB/01-create-account.spec.ts create mode 100644 tests/suites/Chats/02-ChatsUserA.suite.ts create mode 100644 tests/suites/Chats/03-ChatsUserB.suite.ts diff --git a/.github/workflows/ui-automated-tests.yml b/.github/workflows/ui-automated-tests.yml index 2ddd1c4a969..91c1c2969c1 100644 --- a/.github/workflows/ui-automated-tests.yml +++ b/.github/workflows/ui-automated-tests.yml @@ -222,6 +222,123 @@ jobs: with: name: appium-log-macos path: ./appium.log + + - name: Upload test accounts for Chat + uses: actions/upload-artifact@v3 + if: always() + with: + name: test-accounts + path: ./tests/fixtures/users/mac2/ + + - name: Add label if any of test jobs failed + if: failure() + uses: buildsville/add-remove-label@v2.0.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + labels: | + Failed Automated Test + type: add + + test-mac-chats: + strategy: + matrix: + job: ["chatA", "chatB"] + needs: test-mac + runs-on: macos-13 + + steps: + - name: Checkout testing directory ๐Ÿ”– + uses: actions/checkout@v3 + + - name: Download the MacOS app ๐Ÿ—ณ๏ธ + uses: actions/download-artifact@v3 + with: + name: Uplink-macos-latest + path: ./apps + + - name: Extract user data from artifact + uses: actions/download-artifact@v3 + with: + name: test-accounts + path: ./tests/fixtures/users/mac2/ + + - name: Enable opening app not codesigned ๐Ÿ–ฅ๏ธ + run: sudo spctl --master-disable + + - name: Copy DMG to Appium Apps Directory ๐Ÿ’ฟ + working-directory: ./apps + run: | + unzip Uplink-Mac-Universal.zip + cp -r ./Uplink.app /Applications/ + sudo xattr -r -d com.apple.quarantine /Applications/Uplink.app + + - name: Setup Node.js ๐Ÿ”จ + uses: actions/setup-node@v3 + with: + node-version: 18 + cache: "npm" + + - name: Cache NPM dependencies ๐Ÿ”จ + uses: actions/cache@v3 + id: cache-mac + with: + path: node_modules + key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }} + + - name: Install NPM dependencies ๐Ÿ“ฆ + if: steps.cache-mac.outputs.cache-hit != 'true' + run: npm ci + + - name: Install Appium Server ๐Ÿ’ป + run: | + npm install -g appium@next + appium -v + + - name: Install Appium Driver ๐Ÿ’ป + run: | + appium driver install mac2 + appium driver list + + - name: Update MacOS runner to not autocorrect text + run: | + defaults write -g NSAutomaticCapitalizationEnabled -bool false + defaults write -g NSAutomaticPeriodSubstitutionEnabled -bool false + defaults write -g NSAutomaticSpellingCorrectionEnabled -bool false + + - name: Delete Cache Folder and copy reusable data + run: | + rm -rf ~/.uplink + + - name: Run Tests on MacOS ๐Ÿงช + run: npm run mac.${{ matrix.job }} + + - name: Upload Test Report - MacOS CI + if: always() + uses: actions/upload-artifact@v3 + with: + name: test-report-macos-${{ matrix.job }} + path: ./test-report/*.xml + + - name: Upload Allure Test Results + if: always() + uses: actions/upload-artifact@v3 + with: + name: test-allure-mac-${{ matrix.job }} + path: ./allure-results/ + + - name: Upload Screenshots for MacOS ๐Ÿ“ท + uses: actions/upload-artifact@v3 + if: failure() + with: + name: appium-screenshots-macos-${{ matrix.job }} + path: ./test-results + + - name: Upload Appium Log for MacOS ๐Ÿ“ท + uses: actions/upload-artifact@v3 + if: failure() + with: + name: appium-log-macos-${{ matrix.job }} + path: ./appium.log - name: Add label if any of test jobs failed if: failure() @@ -467,7 +584,7 @@ jobs: publish-test-results: if: always() needs: - [build-mac, build-windows, test-mac, test-windows-chats, test-windows] + [build-mac, build-windows, test-mac, test-mac-chats, test-windows-chats, test-windows] runs-on: ubuntu-latest permissions: checks: write @@ -481,6 +598,18 @@ jobs: with: name: test-report-macos-ci path: artifacts + + - name: Download Test Report for MacOS Chat A + uses: actions/download-artifact@v3 + with: + name: test-report-macos-chatA + path: artifacts + + - name: Download Test Report for MacOS Chat B + uses: actions/download-artifact@v3 + with: + name: test-report-macos-chatB + path: artifacts - name: Download Test Report for Windows Chats uses: actions/download-artifact@v3 @@ -499,6 +628,18 @@ jobs: with: name: test-allure-mac-ci path: allure + + - name: Download Allure Results for MacOS Chat A + uses: actions/download-artifact@v3 + with: + name: test-allure-mac-chatA + path: allure + + - name: Download Allure Results for MacOS Chat B + uses: actions/download-artifact@v3 + with: + name: test-allure-mac-chatB + path: allure - name: Download Allure Results for Windows CI uses: actions/download-artifact@v3 @@ -562,6 +703,7 @@ jobs: build-mac, build-windows, test-mac, + test-mac-chats, test-windows-chats, test-windows, publish-test-results, @@ -588,8 +730,13 @@ jobs: uplink-windows-assets Uplink-macos-latest test-report-macos-ci + test-report-macos-chatA + test-report-macos-chatB test-report-windows-ci test-report-windows-chats test-allure-mac-ci + test-allure-mac-chatA + test-allure-mac-chatB test-allure-windows-ci test-allure-windows-chats + test-accounts diff --git a/config/wdio.mac.chatA.conf.ts b/config/wdio.mac.chatA.conf.ts new file mode 100644 index 00000000000..cac831eacd5 --- /dev/null +++ b/config/wdio.mac.chatA.conf.ts @@ -0,0 +1,144 @@ +import "module-alias/register"; +import allureReporter from '@wdio/allure-reporter' +import { config as sharedConfig } from '@config/wdio.shared.conf'; +import { homedir } from "os"; +import { join } from "path"; +import { MACOS_BUNDLE_ID, MACOS_DRIVER } from "@helpers/constants"; +const fsp = require("fs").promises; +const { readFileSync, rmSync } = require("fs"); + +// @ts-expect-error +export const config: WebdriverIO.Config = { + ...sharedConfig, + ...{ + // + // ================== + // Specify Test Files + // ================== + // Define which test specs should run. The pattern is relative to the directory + // from which `wdio` was called. + // + // The specs are defined as an array of spec files (optionally using wildcards + // that will be expanded). The test for each spec file will be run in a separate + // worker process. In order to have a group of spec files run in the same worker + // process simply enclose them in an array within the specs array. + // + // If you are calling `wdio` from an NPM script (see https://docs.npmjs.com/cli/run-script), + // then the current working directory is where your `package.json` resides, so `wdio` + // will be called from there. + // + specs: [join(process.cwd(), "./tests/suites/Chats/02-ChatsUserA.suite.ts")], + // Patterns to exclude. + exclude: [ + // 'path/to/excluded/files' + ], + specFileRetries: 0, + // + // ============ + // Capabilities + // ============ + // Define your capabilities here. WebdriverIO can run multiple capabilities at the same + // time. Depending on the number of capabilities, WebdriverIO launches several test + // sessions. Within your capabilities you can overwrite the spec and exclude options in + // order to group specific specs to a specific capability. + // + // + // If you have trouble getting all important capabilities together, check out the + // Sauce Labs platform configurator - a great tool to configure your capabilities: + // https://docs.saucelabs.com/reference/platforms-configurator + // + port: 4723, + path: '/', + capabilities: { + userA: { + capabilities: { + platformName: "mac", + "appium:automationName": MACOS_DRIVER, + "appium:bundleId": MACOS_BUNDLE_ID, + "appium:arguments": ["--path", join(process.cwd() + "/tests/fixtures/users/mac2/ChatUserA")], + "appium:systemPort": 4724, + } + }, + } + , + // + // =================== + // Test Configurations + // =================== + // Define all options that are relevant for the WebdriverIO instance here + // + reporters: [ + ["spec", + { + showPreface: false, + }, + ], + ['allure', + { + outputDir: './allure-results', + disableWebdriverStepsReporting: true, + disableWebdriverScreenshotsReporting: false, + } + ], + ['junit', + { + outputDir: './test-report/', + outputFileFormat: function (options) { + return `test-results-macos-chatA-${options.cid}.xml`; + } + } + ], + ], + // + // ===== + // Hooks + // ===== + // WebdriverIO provides several hooks you can use to interfere with the test process in order to enhance + // it and to build services around it. You can either apply a single function or an array of + // methods to it. If one of them returns with a promise, WebdriverIO will wait until that promise got + // resolved to continue. + onPrepare: async function() { + const cacheFolder = homedir() + "/.uplink/.user"; + const allureResultsFolder = join(process.cwd(), "./allure-results"); + const testReportFolder = join(process.cwd(), "./test-report"); + const testResultsFolder = join(process.cwd(), "./test-results"); + try { + await rmSync(allureResultsFolder, { recursive: true, force: true }); + await rmSync(testReportFolder, { recursive: true, force: true }); + await rmSync(testResultsFolder, { recursive: true, force: true }); + console.log("Deleted Artifacts Folders Successfully!"); + } catch (error) { + console.error( + `Got an error trying to delete artifacts folders: ${error.message}` + ); + } + try { + await rmSync(cacheFolder, { recursive: true, force: true }); + console.log("Deleted Cache Folder Successfully!"); + } catch (error) { + console.error( + `Got an error trying to delete Cache Folder: ${error.message}` + ); + } + }, + + afterTest: async function (test, describe, { error }) { + if (error) { + let imageFile = await driver.takeScreenshot(); + const imageFolder = join(process.cwd(), "./test-results/macos-chatA", test.parent); + const imageTitle = test.title + " - Failed.png" + await fsp.mkdir(imageFolder, {recursive: true}); + await fsp.writeFile( + imageFolder + "/" + imageTitle, + imageFile, + "base64" + ); + + // Add to Screenshot to Allure Reporter + const data = await readFileSync(`${imageFolder}/${imageTitle}`); + allureReporter.addAttachment(imageTitle, data, 'image/png') + } + }, + } + +} \ No newline at end of file diff --git a/config/wdio.mac.chatB.conf.ts b/config/wdio.mac.chatB.conf.ts new file mode 100644 index 00000000000..499f3643963 --- /dev/null +++ b/config/wdio.mac.chatB.conf.ts @@ -0,0 +1,144 @@ +import "module-alias/register"; +import allureReporter from '@wdio/allure-reporter' +import { config as sharedConfig } from '@config/wdio.shared.conf'; +import { homedir } from "os"; +import { join } from "path"; +import { MACOS_BUNDLE_ID, MACOS_DRIVER } from "@helpers/constants"; +const fsp = require("fs").promises; +const { readFileSync, rmSync } = require("fs"); + +// @ts-expect-error +export const config: WebdriverIO.Config = { + ...sharedConfig, + ...{ + // + // ================== + // Specify Test Files + // ================== + // Define which test specs should run. The pattern is relative to the directory + // from which `wdio` was called. + // + // The specs are defined as an array of spec files (optionally using wildcards + // that will be expanded). The test for each spec file will be run in a separate + // worker process. In order to have a group of spec files run in the same worker + // process simply enclose them in an array within the specs array. + // + // If you are calling `wdio` from an NPM script (see https://docs.npmjs.com/cli/run-script), + // then the current working directory is where your `package.json` resides, so `wdio` + // will be called from there. + // + specs: [join(process.cwd(), "./tests/suites/Chats/03-ChatsUserB.suite.ts")], + // Patterns to exclude. + exclude: [ + // 'path/to/excluded/files' + ], + specFileRetries: 0, + // + // ============ + // Capabilities + // ============ + // Define your capabilities here. WebdriverIO can run multiple capabilities at the same + // time. Depending on the number of capabilities, WebdriverIO launches several test + // sessions. Within your capabilities you can overwrite the spec and exclude options in + // order to group specific specs to a specific capability. + // + // + // If you have trouble getting all important capabilities together, check out the + // Sauce Labs platform configurator - a great tool to configure your capabilities: + // https://docs.saucelabs.com/reference/platforms-configurator + // + port: 4723, + path: '/', + capabilities: { + userA: { + capabilities: { + platformName: "mac", + "appium:automationName": MACOS_DRIVER, + "appium:bundleId": MACOS_BUNDLE_ID, + "appium:arguments": ["--path", join(process.cwd() + "/tests/fixtures/users/mac2/ChatUserA")], + "appium:systemPort": 4724, + } + }, + } + , + // + // =================== + // Test Configurations + // =================== + // Define all options that are relevant for the WebdriverIO instance here + // + reporters: [ + ["spec", + { + showPreface: false, + }, + ], + ['allure', + { + outputDir: './allure-results', + disableWebdriverStepsReporting: true, + disableWebdriverScreenshotsReporting: false, + } + ], + ['junit', + { + outputDir: './test-report/', + outputFileFormat: function (options) { + return `test-results-macos-chatB-${options.cid}.xml`; + } + } + ], + ], + // + // ===== + // Hooks + // ===== + // WebdriverIO provides several hooks you can use to interfere with the test process in order to enhance + // it and to build services around it. You can either apply a single function or an array of + // methods to it. If one of them returns with a promise, WebdriverIO will wait until that promise got + // resolved to continue. + onPrepare: async function() { + const cacheFolder = homedir() + "/.uplink/.user"; + const allureResultsFolder = join(process.cwd(), "./allure-results"); + const testReportFolder = join(process.cwd(), "./test-report"); + const testResultsFolder = join(process.cwd(), "./test-results"); + try { + await rmSync(allureResultsFolder, { recursive: true, force: true }); + await rmSync(testReportFolder, { recursive: true, force: true }); + await rmSync(testResultsFolder, { recursive: true, force: true }); + console.log("Deleted Artifacts Folders Successfully!"); + } catch (error) { + console.error( + `Got an error trying to delete artifacts folders: ${error.message}` + ); + } + try { + await rmSync(cacheFolder, { recursive: true, force: true }); + console.log("Deleted Cache Folder Successfully!"); + } catch (error) { + console.error( + `Got an error trying to delete Cache Folder: ${error.message}` + ); + } + }, + + afterTest: async function (test, describe, { error }) { + if (error) { + let imageFile = await driver.takeScreenshot(); + const imageFolder = join(process.cwd(), "./test-results/macos-chatB", test.parent); + const imageTitle = test.title + " - Failed.png" + await fsp.mkdir(imageFolder, {recursive: true}); + await fsp.writeFile( + imageFolder + "/" + imageTitle, + imageFile, + "base64" + ); + + // Add to Screenshot to Allure Reporter + const data = await readFileSync(`${imageFolder}/${imageTitle}`); + allureReporter.addAttachment(imageTitle, data, 'image/png') + } + }, + } + +} \ No newline at end of file diff --git a/package.json b/package.json index 6717320d580..20459a6fbaf 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,8 @@ "description": "An automation testing framework built with WebdriverIO and Appium to test Uplink Desktop app", "scripts": { "mac.app": "wdio config/wdio.mac.app.conf.ts", + "mac.chatA": "wdio config/wdio.mac.chatA.conf.ts", + "mac.chatB": "wdio config/wdio.mac.chatB.conf.ts", "mac.ci": "wdio config/wdio.mac.ci.conf.ts", "mac.multiremote": "wdio config/wdio.mac.multiremote.conf.ts", "windows.app": "wdio config/wdio.windows.app.conf.ts", diff --git a/tests/specs/reusable-accounts/ChatUserA/01-create-account.spec.ts b/tests/specs/reusable-accounts/ChatUserA/01-create-account.spec.ts new file mode 100644 index 00000000000..4fb4ccdbfc8 --- /dev/null +++ b/tests/specs/reusable-accounts/ChatUserA/01-create-account.spec.ts @@ -0,0 +1,20 @@ +import "module-alias/register"; +import { + loginWithTestUser, +} from "@helpers/commands"; +import { USER_A_INSTANCE } from "@helpers/constants"; +import FriendsScreen from "@screenobjects/friends/FriendsScreen"; +import WelcomeScreen from "@screenobjects/welcome-screen/WelcomeScreen"; +let friendsScreenFirstUser = new FriendsScreen(USER_A_INSTANCE); +let welcomeScreenFirstUser = new WelcomeScreen(USER_A_INSTANCE); + + +export default async function createChatAccountsTests() { + it("Chat User A - Login with account previously created", async () => { + // Login with account previously created + await loginWithTestUser(); + await welcomeScreenFirstUser.validateWelcomeScreenIsShown(); + await welcomeScreenFirstUser.goToFriends() + await friendsScreenFirstUser.validateFriendsScreenIsShown(); + }) +} diff --git a/tests/specs/reusable-accounts/ChatUserB/01-create-account.spec.ts b/tests/specs/reusable-accounts/ChatUserB/01-create-account.spec.ts new file mode 100644 index 00000000000..43353088b42 --- /dev/null +++ b/tests/specs/reusable-accounts/ChatUserB/01-create-account.spec.ts @@ -0,0 +1,20 @@ +import "module-alias/register"; +import { + loginWithTestUser, +} from "@helpers/commands"; +import { USER_A_INSTANCE } from "@helpers/constants"; +import FriendsScreen from "@screenobjects/friends/FriendsScreen"; +import WelcomeScreen from "@screenobjects/welcome-screen/WelcomeScreen"; +let friendsScreenFirstUser = new FriendsScreen(USER_A_INSTANCE); +let welcomeScreenFirstUser = new WelcomeScreen(USER_A_INSTANCE); + + +export default async function createChatAccountsTests() { + it("Chat User B - Login with account previously created", async () => { + // Login with account previously created + await loginWithTestUser(); + await welcomeScreenFirstUser.validateWelcomeScreenIsShown(); + await welcomeScreenFirstUser.goToFriends() + await friendsScreenFirstUser.validateFriendsScreenIsShown(); + }) +} diff --git a/tests/suites/Chats/02-ChatsUserA.suite.ts b/tests/suites/Chats/02-ChatsUserA.suite.ts new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/suites/Chats/03-ChatsUserB.suite.ts b/tests/suites/Chats/03-ChatsUserB.suite.ts new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/suites/MainTests/01-UplinkTests.suite.ts b/tests/suites/MainTests/01-UplinkTests.suite.ts index a0c3211f069..e7cbe61099e 100644 --- a/tests/suites/MainTests/01-UplinkTests.suite.ts +++ b/tests/suites/MainTests/01-UplinkTests.suite.ts @@ -13,6 +13,7 @@ import settingsAbout from "@specs/11-settings-about.spec"; import settingsLicenses from "@specs/12-settings-licenses.spec"; import settingsDeveloper from "@specs/13-settings-developer.spec"; import friends from "@specs/04-friends.spec"; +import createReusableAccounts from "@specs/14-create-reusable-accounts.spec"; describe("MacOS Tests", function () { describe("Create Pin and Account Tests", createAccount.bind(this)); @@ -29,4 +30,5 @@ describe("MacOS Tests", function () { describe("Settings Licenses Tests", settingsLicenses.bind(this)); describe("Settings Developer Tests", settingsDeveloper.bind(this)); describe("Friends Screen Tests", friends.bind(this)); + describe("Create Reusable Accounts Tests", createReusableAccounts.bind(this)); }); From 872c3e34c28269821fec7dfca794a0e5c548e38d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Carden=CC=83a?= <35935591+luisecm@users.noreply.github.com> Date: Tue, 31 Oct 2023 11:32:19 -0600 Subject: [PATCH 02/22] chore(appium): update tests to save user keys --- config/wdio.mac.app.conf.ts | 2 +- tests/specs/01-create-account.spec.ts | 2 +- tests/specs/05-settings-profile.spec.ts | 22 ++- .../specs/14-create-reusable-accounts.spec.ts | 142 ++++++++++-------- .../ChatUserA/01-create-account.spec.ts | 2 +- .../ChatUserB/01-create-account.spec.ts | 2 +- tests/suites/Chats/02-ChatsUserA.suite.ts | 6 + tests/suites/Chats/03-ChatsUserB.suite.ts | 6 + .../suites/MainTests/01-UplinkTests.suite.ts | 2 - .../MainTests/03-CreateAccountTests.suite.ts | 6 + 10 files changed, 115 insertions(+), 77 deletions(-) create mode 100644 tests/suites/MainTests/03-CreateAccountTests.suite.ts diff --git a/config/wdio.mac.app.conf.ts b/config/wdio.mac.app.conf.ts index 8a77ab95915..381336b140a 100644 --- a/config/wdio.mac.app.conf.ts +++ b/config/wdio.mac.app.conf.ts @@ -27,7 +27,7 @@ export const config: WebdriverIO.Config = { // then the current working directory is where your `package.json` resides, so `wdio` // will be called from there. // - specs: [join(process.cwd(), "./tests/suites/MainTests/01-UplinkTests.suite.ts")], + specs: [join(process.cwd(), "./tests/suites/MainTests/*Tests*.suite.ts")], // Patterns to exclude. exclude: [ // 'path/to/excluded/files' diff --git a/tests/specs/01-create-account.spec.ts b/tests/specs/01-create-account.spec.ts index e18974fa5b4..0d7ba28097d 100644 --- a/tests/specs/01-create-account.spec.ts +++ b/tests/specs/01-create-account.spec.ts @@ -192,7 +192,7 @@ export default async function createAccount() { }); it("Enter valid username to continue", async () => { - await createUserFirstUser.enterUsername("Test123"); + await createUserFirstUser.enterUsername("ChatUserA"); const statusOfButton = await createPinFirstUser.getStatusOfCreateAccountButton(); await expect(statusOfButton).toEqual("true"); diff --git a/tests/specs/05-settings-profile.spec.ts b/tests/specs/05-settings-profile.spec.ts index 4e7bc0320b3..2c47f23c5bc 100644 --- a/tests/specs/05-settings-profile.spec.ts +++ b/tests/specs/05-settings-profile.spec.ts @@ -2,6 +2,7 @@ import "module-alias/register"; import CropImageProfileModal from "@screenobjects/settings/CropToolProfileModal"; import FilesScreen from "@screenobjects/files/FilesScreen"; import SettingsProfileScreen from "@screenobjects/settings/SettingsProfileScreen"; +import { grabCacheFolder, saveTestKeys } from "@helpers/commands"; import { USER_A_INSTANCE } from "@helpers/constants"; let cropProfileFirstUser = new CropImageProfileModal(USER_A_INSTANCE); let filesScreenFirstUser = new FilesScreen(USER_A_INSTANCE); @@ -66,7 +67,7 @@ export default async function settingsProfile() { // Assert username and status placeholder values are displayed const usernameInput = await settingsProfileFirstUser.usernameInput; - await expect(usernameInput).toHaveTextContaining("Test123"); + await expect(usernameInput).toHaveTextContaining("ChatUserA"); const statusInput = await settingsProfileFirstUser.statusInput; await expect(statusInput).toHaveTextContaining(""); @@ -228,8 +229,7 @@ export default async function settingsProfile() { await settingsProfileFirstUser.waitUntilNotificationIsClosed(); }); - // Skipping test - requires adding validation to ensure clipboard is not empty before pasting - xit("Settings Profile - Copied ID can be placed on any text field", async () => { + it("Settings Profile - Copied ID can be placed on any text field", async () => { // Paste copied DID Key into Status Input await settingsProfileFirstUser.pasteUserKeyInStatus(); @@ -238,6 +238,14 @@ export default async function settingsProfile() { await settingsProfileFirstUser.getStatusInputElement(); await expect(statusInputText).toHaveTextContaining("did:key:"); + const didkey = await settingsProfileFirstUser.getCopiedDidFromStatusInput(); + const username = "ChatUserA"; + // Grab cache folder and restart + await saveTestKeys(username, didkey, USER_A_INSTANCE); + + // Update banner picture from user A + await grabCacheFolder(username, USER_A_INSTANCE); + // Clear value from status input await settingsProfileFirstUser.deleteStatus(); }); @@ -277,7 +285,7 @@ export default async function settingsProfile() { ); // Clear value from username input, then enter a valid value again - await settingsProfileFirstUser.enterUsername("Test123"); + await settingsProfileFirstUser.enterUsername("ChatUserA"); }); it("Settings Profile - Username - Spaces are not allowed", async () => { @@ -294,7 +302,7 @@ export default async function settingsProfile() { ); // Clear value from username input, then enter a valid value again - await settingsProfileFirstUser.enterUsername("Test123"); + await settingsProfileFirstUser.enterUsername("ChatUserA"); }); it("Settings Profile - Username with non-alphanumeric characters", async () => { @@ -312,7 +320,7 @@ export default async function settingsProfile() { ); // Clear value from username input, then enter a valid value again - await settingsProfileFirstUser.enterUsername("Test123"); + await settingsProfileFirstUser.enterUsername("ChatUserA"); }); it("Settings Profile - Username with more than 32 characters", async () => { @@ -331,7 +339,7 @@ export default async function settingsProfile() { ); // Clear value from username input, then enter a valid value again - await settingsProfileFirstUser.enterUsername("Test123"); + await settingsProfileFirstUser.enterUsername("ChatUserA"); // Wait for toast notification to be closed before starting next tests await settingsProfileFirstUser.waitUntilNotificationIsClosed(); diff --git a/tests/specs/14-create-reusable-accounts.spec.ts b/tests/specs/14-create-reusable-accounts.spec.ts index 052a1fb1d4a..22664533967 100644 --- a/tests/specs/14-create-reusable-accounts.spec.ts +++ b/tests/specs/14-create-reusable-accounts.spec.ts @@ -1,29 +1,61 @@ import "module-alias/register"; -import { - createNewUser, - grabCacheFolder, - resetApp, - saveTestKeys, -} from "@helpers/commands"; +import { grabCacheFolder, maximizeWindow, saveTestKeys } from "@helpers/commands"; import { USER_A_INSTANCE } from "@helpers/constants"; +import CreatePinScreen from "@screenobjects/account-creation/CreatePinScreen"; +import CreateUserScreen from "@screenobjects/account-creation/CreateUserScreen"; import CropImageProfileModal from "@screenobjects/settings/CropToolProfileModal"; import SettingsProfileScreen from "@screenobjects/settings/SettingsProfileScreen"; import WelcomeScreen from "@screenobjects/welcome-screen/WelcomeScreen"; +let createPinFirstUser = new CreatePinScreen(USER_A_INSTANCE); +let createUserFirstUser = new CreateUserScreen(USER_A_INSTANCE); let cropProfileFirstUser = new CropImageProfileModal(USER_A_INSTANCE); let settingsProfileFirstUser = new SettingsProfileScreen(USER_A_INSTANCE); let welcomeScreenFirstUser = new WelcomeScreen(USER_A_INSTANCE); -export default async function createReusableAccounts() { - it("Create reusable account - Chat User A", async () => { - await resetApp(USER_A_INSTANCE); - // Create New User and go to Settings Profile Screen - const username = "ChatUserA"; - await createNewUser(username); +export default async function createSecondAccount() { + it("Create Account button should be disabled if no pin has been entered", async () => { + const statusOfButton = + await createPinFirstUser.getStatusOfCreateAccountButton(); + await expect(statusOfButton).toEqual("false"); + }); + + it("Unlock Screen - Reset Account is shown after right clicking on Help Button", async () => { + // Right click on Help Button to show the help menu + await createPinFirstUser.openHelpButtonMenu(); + + // Right click again on Help Button to hide the help menu + await createPinFirstUser.openHelpButtonMenu(); + }); + + it("Enter a valid pin and continue creating a username", async () => { + await createPinFirstUser.enterPin("1234"); + const statusOfButton = + await createPinFirstUser.getStatusOfCreateAccountButton(); + await expect(statusOfButton).toEqual("true"); + await createPinFirstUser.clickOnCreateAccount(); + await createUserFirstUser.waitForIsShown(true); + }); + + it("Enter valid username to continue", async () => { + await createUserFirstUser.enterUsername("ChatUserB"); + const statusOfButton = + await createPinFirstUser.getStatusOfCreateAccountButton(); + await expect(statusOfButton).toEqual("true"); + await createUserFirstUser.clickOnCreateAccount(); + await welcomeScreenFirstUser.waitForIsShown(true); + + // Maximize Window on Execution + await maximizeWindow(USER_A_INSTANCE); + }); + + it("Go to Settings with Chat User B", async () => { + // Go to Settings Screen and select the Settings Screen to validate await welcomeScreenFirstUser.goToSettings(); await settingsProfileFirstUser.waitForIsShown(true); }); - it("Add profile picture - Chat User A", async () => { + it("Settings Profile - Profile Picture - Crop Image and add profile picture", async () => { + // Click on profile picture upload button and select the file logo.jpg await settingsProfileFirstUser.selectProfilePicture( "./tests/fixtures/logo.jpg" ); @@ -31,86 +63,68 @@ export default async function createReusableAccounts() { // Validate Crop Tool Modal is displayed await cropProfileFirstUser.validateCropToolModalIsShown(); - // Do not change the size of picture and just confirm on crop modal + // Click three times on increase button, then one time on decrease button + await cropProfileFirstUser.clickMultipleTimesIncreaseButton(3); + await cropProfileFirstUser.clickOnDecreaseRangeButton(); + + // Validate final value shown for zoom slider is 1 + const rangeValueText = await cropProfileFirstUser.cropImageRangeValueText; + await expect(rangeValueText).toHaveTextContaining("1.2"); + + // Click on confirm button to save await cropProfileFirstUser.clickOnConfirmButton(); // Validate new profile picture is displayed await settingsProfileFirstUser.validateProfilePictureIsShown(); }); - it("Add banner picture - Chat User A", async () => { + // Needs visual validation steps to ensure that picture was actually loaded matches with expected image + it("Settings Profile - Crop banner and add banner picture", async () => { + // Click on banner picture upload button and select the file banner.jpg await settingsProfileFirstUser.selectBannerPicture( "./tests/fixtures/banner.jpg" ); - }); - - it("Save test account - Chat User A", async () => { - // Click on Copy ID button and assert Toast Notification is displayed - const username = "ChatUserA"; - await settingsProfileFirstUser.clickOnCopyIDButton(); - - // Wait for toast notification to be closed - await settingsProfileFirstUser.waitUntilNotificationIsClosed(); - - // Paste copied DID Key into Status Input - await settingsProfileFirstUser.pasteUserKeyInStatus(); - const didkey = await settingsProfileFirstUser.getCopiedDidFromStatusInput(); - - // Grab cache folder and restart - await saveTestKeys(username, didkey, USER_A_INSTANCE); - - // Update profile picture from user A - - // Update banner picture from user A - await grabCacheFolder(username, USER_A_INSTANCE); - await resetApp(USER_A_INSTANCE); - }); - - it("Create reusable account - Chat User B", async () => { - // Create New User and go to Settings Profile Screen - const username = "ChatUserB"; - await createNewUser(username); - await welcomeScreenFirstUser.goToSettings(); - await settingsProfileFirstUser.waitForIsShown(true); - }); - - it("Add profile picture - Chat User B", async () => { - await settingsProfileFirstUser.selectProfilePicture( - "./tests/fixtures/second-profile.png" - ); // Validate Crop Tool Modal is displayed await cropProfileFirstUser.validateCropToolModalIsShown(); - // Do not change the size of picture and just confirm on crop modal + // Change the size of picture and click on confirm button to save + await cropProfileFirstUser.clickOnIncreaseRangeButton(); await cropProfileFirstUser.clickOnConfirmButton(); - // Validate new profile picture is displayed - await settingsProfileFirstUser.validateProfilePictureIsShown(); + // Validate new banner picture is displayed + await settingsProfileFirstUser.validateBannerPictureIsShown(); }); - it("Add banner picture - Chat User B", async () => { - it("Settings Profile - Change banner picture", async () => { - await settingsProfileFirstUser.selectBannerPicture( - "./tests/fixtures/second-banner.jpg" - ); - }); - }); + it("Settings Profile - Click On Copy ID Button", async () => { + // Wait for toast notification to be closed before starting test + await settingsProfileFirstUser.waitUntilNotificationIsClosed(); - it("Save test account - Chat User B", async () => { - const username = "ChatUserB"; // Click on Copy ID button and assert Toast Notification is displayed await settingsProfileFirstUser.clickOnCopyIDButton(); // Wait for toast notification to be closed await settingsProfileFirstUser.waitUntilNotificationIsClosed(); + }); + it("Settings Profile - Copied ID can be placed on any text field", async () => { // Paste copied DID Key into Status Input await settingsProfileFirstUser.pasteUserKeyInStatus(); - const didkey = await settingsProfileFirstUser.getCopiedDidFromStatusInput(); + // Ensure that value placed in Status is the did key from the user + const statusInputText = + await settingsProfileFirstUser.getStatusInputElement(); + await expect(statusInputText).toHaveTextContaining("did:key:"); + + const didkey = await settingsProfileFirstUser.getCopiedDidFromStatusInput(); + const username = "ChatUserA"; // Grab cache folder and restart await saveTestKeys(username, didkey, USER_A_INSTANCE); + + // Update banner picture from user A await grabCacheFolder(username, USER_A_INSTANCE); + + // Clear value from status input + await settingsProfileFirstUser.deleteStatus(); }); } diff --git a/tests/specs/reusable-accounts/ChatUserA/01-create-account.spec.ts b/tests/specs/reusable-accounts/ChatUserA/01-create-account.spec.ts index 4fb4ccdbfc8..57bc26fe228 100644 --- a/tests/specs/reusable-accounts/ChatUserA/01-create-account.spec.ts +++ b/tests/specs/reusable-accounts/ChatUserA/01-create-account.spec.ts @@ -9,7 +9,7 @@ let friendsScreenFirstUser = new FriendsScreen(USER_A_INSTANCE); let welcomeScreenFirstUser = new WelcomeScreen(USER_A_INSTANCE); -export default async function createChatAccountsTests() { +export default async function friendRequestUserATests() { it("Chat User A - Login with account previously created", async () => { // Login with account previously created await loginWithTestUser(); diff --git a/tests/specs/reusable-accounts/ChatUserB/01-create-account.spec.ts b/tests/specs/reusable-accounts/ChatUserB/01-create-account.spec.ts index 43353088b42..996da0c32fe 100644 --- a/tests/specs/reusable-accounts/ChatUserB/01-create-account.spec.ts +++ b/tests/specs/reusable-accounts/ChatUserB/01-create-account.spec.ts @@ -9,7 +9,7 @@ let friendsScreenFirstUser = new FriendsScreen(USER_A_INSTANCE); let welcomeScreenFirstUser = new WelcomeScreen(USER_A_INSTANCE); -export default async function createChatAccountsTests() { +export default async function friendRequestUserBTests() { it("Chat User B - Login with account previously created", async () => { // Login with account previously created await loginWithTestUser(); diff --git a/tests/suites/Chats/02-ChatsUserA.suite.ts b/tests/suites/Chats/02-ChatsUserA.suite.ts index e69de29bb2d..c5c5f372a9e 100644 --- a/tests/suites/Chats/02-ChatsUserA.suite.ts +++ b/tests/suites/Chats/02-ChatsUserA.suite.ts @@ -0,0 +1,6 @@ +import "module-alias/register"; +import friendRequestUserATests from "@specs/reusable-accounts/ChatUserA/01-create-account.spec"; + +describe("MacOS Chats Tests - User A", async () => { + describe("Friends and Chat Main Tests", friendRequestUserATests.bind(this)); +}) \ No newline at end of file diff --git a/tests/suites/Chats/03-ChatsUserB.suite.ts b/tests/suites/Chats/03-ChatsUserB.suite.ts index e69de29bb2d..10c4ba3dcfc 100644 --- a/tests/suites/Chats/03-ChatsUserB.suite.ts +++ b/tests/suites/Chats/03-ChatsUserB.suite.ts @@ -0,0 +1,6 @@ +import "module-alias/register"; +import friendRequestUserBTests from "@specs/reusable-accounts/ChatUserB/01-create-account.spec"; + +describe("MacOS Chats Tests - User B", async () => { + describe("Friends and Chat Main Tests", friendRequestUserBTests.bind(this)); +}) \ No newline at end of file diff --git a/tests/suites/MainTests/01-UplinkTests.suite.ts b/tests/suites/MainTests/01-UplinkTests.suite.ts index e7cbe61099e..a0c3211f069 100644 --- a/tests/suites/MainTests/01-UplinkTests.suite.ts +++ b/tests/suites/MainTests/01-UplinkTests.suite.ts @@ -13,7 +13,6 @@ import settingsAbout from "@specs/11-settings-about.spec"; import settingsLicenses from "@specs/12-settings-licenses.spec"; import settingsDeveloper from "@specs/13-settings-developer.spec"; import friends from "@specs/04-friends.spec"; -import createReusableAccounts from "@specs/14-create-reusable-accounts.spec"; describe("MacOS Tests", function () { describe("Create Pin and Account Tests", createAccount.bind(this)); @@ -30,5 +29,4 @@ describe("MacOS Tests", function () { describe("Settings Licenses Tests", settingsLicenses.bind(this)); describe("Settings Developer Tests", settingsDeveloper.bind(this)); describe("Friends Screen Tests", friends.bind(this)); - describe("Create Reusable Accounts Tests", createReusableAccounts.bind(this)); }); diff --git a/tests/suites/MainTests/03-CreateAccountTests.suite.ts b/tests/suites/MainTests/03-CreateAccountTests.suite.ts new file mode 100644 index 00000000000..44e4e7f876e --- /dev/null +++ b/tests/suites/MainTests/03-CreateAccountTests.suite.ts @@ -0,0 +1,6 @@ +import "module-alias/register"; +import createSecondAccount from "@specs/14-create-reusable-accounts.spec"; + +describe("MacOS Tests - Create Second Account", function () { + describe("Create Pin and Account Tests", createSecondAccount.bind(this)); +}) \ No newline at end of file From 9db4acb6e066d083c89b140f19ef1c2c37080e53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Carden=CC=83a?= <35935591+luisecm@users.noreply.github.com> Date: Tue, 31 Oct 2023 12:54:44 -0600 Subject: [PATCH 03/22] chore(appium): update max instances on config file --- config/wdio.mac.app.conf.ts | 6 +++++- tests/specs/14-create-reusable-accounts.spec.ts | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/config/wdio.mac.app.conf.ts b/config/wdio.mac.app.conf.ts index 381336b140a..6f5eb064412 100644 --- a/config/wdio.mac.app.conf.ts +++ b/config/wdio.mac.app.conf.ts @@ -27,7 +27,11 @@ export const config: WebdriverIO.Config = { // then the current working directory is where your `package.json` resides, so `wdio` // will be called from there. // - specs: [join(process.cwd(), "./tests/suites/MainTests/*Tests*.suite.ts")], + maxInstances: 1, + specs: [ + [join(process.cwd(), "./tests/suites/MainTests/03-CreateAccountTests.suite.ts")], + [join(process.cwd(), "./tests/suites/MainTests/01-UplinkTests.suite.ts")] + ], // Patterns to exclude. exclude: [ // 'path/to/excluded/files' diff --git a/tests/specs/14-create-reusable-accounts.spec.ts b/tests/specs/14-create-reusable-accounts.spec.ts index 22664533967..b30c1ce0781 100644 --- a/tests/specs/14-create-reusable-accounts.spec.ts +++ b/tests/specs/14-create-reusable-accounts.spec.ts @@ -13,6 +13,22 @@ let settingsProfileFirstUser = new SettingsProfileScreen(USER_A_INSTANCE); let welcomeScreenFirstUser = new WelcomeScreen(USER_A_INSTANCE); export default async function createSecondAccount() { + it("Validate warning texts are displayed on screen", async () => { + const unlockWarningHeader = await createPinFirstUser.unlockWarningHeader; + await unlockWarningHeader.waitForExist(); + await expect(unlockWarningHeader).toHaveTextContaining([ + "LET'S CHOOSE YOUR PASSWORD", + "WELCOME BACK,", + ]); + + const unlockWarningParagraph = + await createPinFirstUser.unlockWarningParagraph; + await unlockWarningParagraph.waitForExist(); + await expect(unlockWarningParagraph).toHaveTextContaining( + "(this is used to encrypt all of the data Uplink stores on your computer when you're not using it so nobody can read your data.)" + ); + }); + it("Create Account button should be disabled if no pin has been entered", async () => { const statusOfButton = await createPinFirstUser.getStatusOfCreateAccountButton(); From 595697748d16e447f3659a3162169a9993bca127 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Carden=CC=83a?= <35935591+luisecm@users.noreply.github.com> Date: Tue, 31 Oct 2023 14:20:41 -0600 Subject: [PATCH 04/22] chore(appium): copy correct data for chat users --- .github/workflows/ui-automated-tests.yml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ui-automated-tests.yml b/.github/workflows/ui-automated-tests.yml index 91c1c2969c1..b7e8f357de0 100644 --- a/.github/workflows/ui-automated-tests.yml +++ b/.github/workflows/ui-automated-tests.yml @@ -242,7 +242,12 @@ jobs: test-mac-chats: strategy: matrix: - job: ["chatA", "chatB"] + job: ["chatA", "chatB"] + include: + - job: "chatA" + username: "ChatUserA" + - job: "chatB" + username: "ChatUserB" needs: test-mac runs-on: macos-13 @@ -305,9 +310,15 @@ jobs: defaults write -g NSAutomaticPeriodSubstitutionEnabled -bool false defaults write -g NSAutomaticSpellingCorrectionEnabled -bool false - - name: Delete Cache Folder and copy reusable data + - if: ${{ matrix.username }} + name: Delete Cache Folder and copy reusable data for ${{ matrix.username }} run: | rm -rf ~/.uplink + cp -r ./testing-uplink/tests/fixtures/users/${{ matrix.username }}/ ~/.uplink + + - name: Show if data was copied correctly + working-directory: ~/.uplink + run: ls -la - name: Run Tests on MacOS ๐Ÿงช run: npm run mac.${{ matrix.job }} From cfd6d4c333aed37f244bfbf3ed63bc91368b66b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Carden=CC=83a?= <35935591+luisecm@users.noreply.github.com> Date: Tue, 31 Oct 2023 16:00:08 -0600 Subject: [PATCH 05/22] chore(appium): list files extracted --- .github/workflows/ui-automated-tests.yml | 15 +++++++++++---- config/wdio.mac.chatB.conf.ts | 2 +- tests/specs/14-create-reusable-accounts.spec.ts | 6 ------ 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ui-automated-tests.yml b/.github/workflows/ui-automated-tests.yml index b7e8f357de0..786b1745640 100644 --- a/.github/workflows/ui-automated-tests.yml +++ b/.github/workflows/ui-automated-tests.yml @@ -228,7 +228,7 @@ jobs: if: always() with: name: test-accounts - path: ./tests/fixtures/users/mac2/ + path: ./tests/fixtures/users/ - name: Add label if any of test jobs failed if: failure() @@ -261,11 +261,16 @@ jobs: name: Uplink-macos-latest path: ./apps - - name: Extract user data from artifact + - name: Download Test User Accounts ๐Ÿ—ณ๏ธ uses: actions/download-artifact@v3 with: name: test-accounts - path: ./tests/fixtures/users/mac2/ + path: ./tests/fixtures/users/ + + - name: List all of the files extracted + run: | + pwd + ls -R - name: Enable opening app not codesigned ๐Ÿ–ฅ๏ธ run: sudo spctl --master-disable @@ -318,7 +323,9 @@ jobs: - name: Show if data was copied correctly working-directory: ~/.uplink - run: ls -la + run: | + pwd + ls -R - name: Run Tests on MacOS ๐Ÿงช run: npm run mac.${{ matrix.job }} diff --git a/config/wdio.mac.chatB.conf.ts b/config/wdio.mac.chatB.conf.ts index 499f3643963..d9650b03d8c 100644 --- a/config/wdio.mac.chatB.conf.ts +++ b/config/wdio.mac.chatB.conf.ts @@ -55,7 +55,7 @@ export const config: WebdriverIO.Config = { platformName: "mac", "appium:automationName": MACOS_DRIVER, "appium:bundleId": MACOS_BUNDLE_ID, - "appium:arguments": ["--path", join(process.cwd() + "/tests/fixtures/users/mac2/ChatUserA")], + "appium:arguments": ["--path", join(process.cwd() + "/tests/fixtures/users/mac2/ChatUserB")], "appium:systemPort": 4724, } }, diff --git a/tests/specs/14-create-reusable-accounts.spec.ts b/tests/specs/14-create-reusable-accounts.spec.ts index b30c1ce0781..60625859d90 100644 --- a/tests/specs/14-create-reusable-accounts.spec.ts +++ b/tests/specs/14-create-reusable-accounts.spec.ts @@ -28,12 +28,6 @@ export default async function createSecondAccount() { "(this is used to encrypt all of the data Uplink stores on your computer when you're not using it so nobody can read your data.)" ); }); - - it("Create Account button should be disabled if no pin has been entered", async () => { - const statusOfButton = - await createPinFirstUser.getStatusOfCreateAccountButton(); - await expect(statusOfButton).toEqual("false"); - }); it("Unlock Screen - Reset Account is shown after right clicking on Help Button", async () => { // Right click on Help Button to show the help menu From 71c875ea315aba83138d4b8f3fd6ef0f9078daec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Carden=CC=83a?= <35935591+luisecm@users.noreply.github.com> Date: Tue, 31 Oct 2023 17:29:51 -0600 Subject: [PATCH 06/22] chore(appium): try using two workflows to improve speed on test --- .github/workflows/ui-automated-tests.yml | 420 +------------------ .github/workflows/ui-automated-windows.yml | 456 +++++++++++++++++++++ config/wdio.mac.chatA.conf.ts | 1 - config/wdio.mac.chatB.conf.ts | 1 - config/wdio.mac.ci.conf.ts | 7 +- 5 files changed, 463 insertions(+), 422 deletions(-) create mode 100644 .github/workflows/ui-automated-windows.yml diff --git a/.github/workflows/ui-automated-tests.yml b/.github/workflows/ui-automated-tests.yml index 786b1745640..f5b2e77781b 100644 --- a/.github/workflows/ui-automated-tests.yml +++ b/.github/workflows/ui-automated-tests.yml @@ -71,64 +71,6 @@ jobs: Failed Automated Test type: add - build-windows: - runs-on: - labels: windows-latest - - steps: - - name: Checkout testing directory ๐Ÿ”– - uses: actions/checkout@v3 - with: - repository: Satellite-im/Uplink - - - name: Install Rust ๐Ÿ’ฟ - uses: actions-rs/toolchain@v1 - with: - toolchain: 1.70.0 - override: true - components: rustfmt, clippy - - - name: Build executable ๐Ÿ–ฅ๏ธ - run: cargo build --release -F production_mode - continue-on-error: true - - - name: Create ZIP archive on Windows ๐Ÿ—ณ๏ธ - run: Compress-Archive -Path target/release/uplink.exe -Destination uplinkWindows.zip - - - name: Copy Extensions ๐Ÿ—ณ๏ธ - run: | - mkdir ./ui/extra/extensions - cp -r ./target/release/emoji_selector.d ./ui/extra/extensions/ - cp -r ./target/release/emoji_selector.dll ./ui/extra/extensions/ - cp -r ./target/release/emoji_selector.dll.exp ./ui/extra/extensions/ - cp -r ./target/release/emoji_selector.dll.lib ./ui/extra/extensions/ - cp -r ./target/release/emoji_selector.pdb ./ui/extra/extensions/ - - - name: Upload Executable โฌ†๏ธ - uses: actions/upload-artifact@v3 - with: - name: Uplink-windows-latest - path: uplinkWindows.zip - - - name: Upload Windows Assets - uses: actions/upload-artifact@v3 - with: - name: uplink-windows-assets - path: | - ui/extra/images/ - ui/extra/prism_langs/ - ui/extra/themes/ - ui/extra/extensions/ - - - name: Add label if any of build jobs failed - if: failure() - uses: buildsville/add-remove-label@v2.0.0 - with: - token: ${{ secrets.GITHUB_TOKEN }} - labels: | - Failed Automated Test - type: add - test-mac: needs: build-mac runs-on: macos-13 @@ -319,7 +261,7 @@ jobs: name: Delete Cache Folder and copy reusable data for ${{ matrix.username }} run: | rm -rf ~/.uplink - cp -r ./testing-uplink/tests/fixtures/users/${{ matrix.username }}/ ~/.uplink + cp -r ./tests/fixtures/users/${{ matrix.username }}/. ~/.uplink - name: Show if data was copied correctly working-directory: ~/.uplink @@ -367,364 +309,12 @@ jobs: Failed Automated Test type: add - test-windows-chats: - needs: build-windows - runs-on: windows-latest - - steps: - - name: Checkout testing directory ๐Ÿ”– - uses: actions/checkout@v3 - - - name: Change resolution on Windows Runner - run: Set-DisplayResolution -Width 1920 -Height 1080 -Force - shell: powershell - - - name: Download the Windows app ๐Ÿ—ณ๏ธ - uses: actions/download-artifact@v3 - with: - name: Uplink-windows-latest - path: ./apps - - - name: Extract .zip into apps Directory ๐Ÿ—ณ๏ธ - run: Expand-Archive -Path ./apps/uplinkWindows.zip -DestinationPath ./apps - - - name: Download the Windows app assets - uses: actions/download-artifact@v3 - with: - name: uplink-windows-assets - path: ./apps - - - name: Copy app to have two instances ๐Ÿ’ฟ - working-directory: ./apps - run: | - cp -r ./uplink.exe ./uplink2.exe - - - name: Move Windows assets to correct locations ๐Ÿ’ฟ - working-directory: ./apps - run: | - mkdir ./bin/extra - mkdir ./extra - mv ./uplink.exe ./bin/ - mv ./uplink2.exe ./bin/ - mv ./images/ ./bin/extra/ - mv ./prism_langs/ ./bin/extra/ - mv ./themes/ ./extra/ - - - name: Setup Node.js ๐Ÿ”จ - uses: actions/setup-node@v3 - with: - node-version: 18 - cache: "npm" - - - name: Cache NPM dependencies ๐Ÿ”จ - uses: actions/cache@v3 - id: cache-windows-chats - with: - path: node_modules - key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }} - - - name: Install NPM dependencies ๐Ÿ“ฆ - if: steps.cache-windows-chats.outputs.cache-hit != 'true' - run: npm ci - - - name: Install Appium Server ๐Ÿ’ป - run: | - npm install -g appium@next - appium -v - - - name: Install Appium Driver ๐Ÿ’ป - run: | - appium driver install --source=npm appium-windows-driver - appium driver list - - - name: Setup FFMPEG to record screen - uses: FedericoCarboni/setup-ffmpeg@v2 - id: setup-ffmpeg - - - name: Delete Cache Folder if exists - Windows - run: If (Test-Path $home/.uplink/.user) {Remove-Item -Recurse -Force $home/.uplink/.user} Else { Break } - shell: powershell - - - name: Run Chat Tests on Windows ๐Ÿงช - run: npm run windows.multiremote - - - name: Upload Test Report - Windows Chats - if: always() - uses: actions/upload-artifact@v3 - with: - name: test-report-windows-chats - path: ./test-report/*.xml - - - name: Upload Allure Test Results - if: always() - uses: actions/upload-artifact@v3 - with: - name: test-allure-windows-chats - path: ./allure-results/ - - - name: Upload Screenshots for Windows - Chats ๐Ÿ“ท - uses: actions/upload-artifact@v3 - if: failure() - with: - name: appium-screenshots-windows-chats - path: ./test-results - - - name: Upload Appium Log for Windows - Chats ๐Ÿ“ท - uses: actions/upload-artifact@v3 - if: failure() - with: - name: appium-log-windows-chats - path: | - ./appium.log - - - name: Add label if any of test jobs failed - if: failure() - uses: buildsville/add-remove-label@v2.0.0 - with: - token: ${{ secrets.GITHUB_TOKEN }} - labels: | - Failed Automated Test - type: add - - test-windows: - needs: build-windows - runs-on: windows-latest - - steps: - - name: Checkout testing directory ๐Ÿ”– - uses: actions/checkout@v3 - - - name: Change resolution on Windows Runner - run: Set-DisplayResolution -Width 1920 -Height 1080 -Force - shell: powershell - - - name: Download the Windows app ๐Ÿ—ณ๏ธ - uses: actions/download-artifact@v3 - with: - name: Uplink-windows-latest - path: ./apps - - - name: Extract .zip into apps Directory ๐Ÿ—ณ๏ธ - run: Expand-Archive -Path ./apps/uplinkWindows.zip -DestinationPath ./apps - - - name: Download the Windows app assets - uses: actions/download-artifact@v3 - with: - name: uplink-windows-assets - path: ./apps - - - name: Move Windows assets to correct locations ๐Ÿ’ฟ - working-directory: ./apps - run: | - mkdir ./bin/extra - mkdir ./extra - mv ./uplink.exe ./bin/ - mv ./images/ ./bin/extra/ - mv ./prism_langs/ ./bin/extra/ - mv ./themes/ ./extra/ - - - name: Setup Node.js ๐Ÿ”จ - uses: actions/setup-node@v3 - with: - node-version: 18 - cache: "npm" - - - name: Cache NPM dependencies ๐Ÿ”จ - uses: actions/cache@v3 - id: cache-windows - with: - path: node_modules - key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }} - - - name: Install NPM dependencies ๐Ÿ“ฆ - if: steps.cache-windows.outputs.cache-hit != 'true' - run: npm ci - - - name: Install and Run Appium Server ๐Ÿ’ป - run: | - npm install -g appium@next - appium -v - - - name: Install Appium Driver ๐Ÿ’ป - run: | - appium driver install --source=npm appium-windows-driver - appium driver list - - - name: Setup FFMPEG to record screen - uses: FedericoCarboni/setup-ffmpeg@v2 - id: setup-ffmpeg - - - name: Delete Cache Folder if exists - Windows - run: If (Test-Path $home/.uplink/.user) {Remove-Item -Recurse -Force $home/.uplink/.user} Else { Break } - shell: powershell - - - name: Run Tests on Windows ๐Ÿงช - id: test-execution-windows - run: npm run windows.ci - - - name: Upload Test Report - Windows CI - if: always() - uses: actions/upload-artifact@v3 - with: - name: test-report-windows-ci - path: ./test-report/*.xml - - - name: Upload Allure Test Results - if: always() - uses: actions/upload-artifact@v3 - with: - name: test-allure-windows-ci - path: ./allure-results/ - - - name: Upload Screenshots for Windows ๐Ÿ“ท - uses: actions/upload-artifact@v3 - if: failure() - with: - name: appium-screenshots-windows - path: ./test-results - - - name: Upload Appium Log for Windows ๐Ÿ“ท - uses: actions/upload-artifact@v3 - if: failure() - with: - name: appium-log-windows - path: ./appium.log - - - name: Add label if any of test jobs failed - if: failure() - uses: buildsville/add-remove-label@v2.0.0 - with: - token: ${{ secrets.GITHUB_TOKEN }} - labels: | - Failed Automated Test - type: add - - publish-test-results: - if: always() - needs: - [build-mac, build-windows, test-mac, test-mac-chats, test-windows-chats, test-windows] - runs-on: ubuntu-latest - permissions: - checks: write - pull-requests: write - contents: write - issues: read - - steps: - - name: Download Test Report for MacOS CI - uses: actions/download-artifact@v3 - with: - name: test-report-macos-ci - path: artifacts - - - name: Download Test Report for MacOS Chat A - uses: actions/download-artifact@v3 - with: - name: test-report-macos-chatA - path: artifacts - - - name: Download Test Report for MacOS Chat B - uses: actions/download-artifact@v3 - with: - name: test-report-macos-chatB - path: artifacts - - - name: Download Test Report for Windows Chats - uses: actions/download-artifact@v3 - with: - name: test-report-windows-chats - path: artifacts - - - name: Download Test Report for Windows CI - uses: actions/download-artifact@v3 - with: - name: test-report-windows-ci - path: artifacts - - - name: Download Allure Results for MacOS CI - uses: actions/download-artifact@v3 - with: - name: test-allure-mac-ci - path: allure - - - name: Download Allure Results for MacOS Chat A - uses: actions/download-artifact@v3 - with: - name: test-allure-mac-chatA - path: allure - - - name: Download Allure Results for MacOS Chat B - uses: actions/download-artifact@v3 - with: - name: test-allure-mac-chatB - path: allure - - - name: Download Allure Results for Windows CI - uses: actions/download-artifact@v3 - with: - name: test-allure-windows-ci - path: allure - - - name: Download Allure Results for Windows Chats - uses: actions/download-artifact@v3 - with: - name: test-allure-windows-chats - path: allure - - - name: Publish Test Results for Tests - uses: EnricoMi/publish-unit-test-result-action/composite@v2 - if: success() - with: - junit_files: "artifacts/**/*.xml" - ignore_runs: true - job_summary: false - compare_to_earlier_commit: false - check_name: "UI Automated Test Results Summary for MacOS/Windows" - - - name: Get Allure history - uses: actions/checkout@v3 - if: success() - continue-on-error: true - with: - ref: gh-pages - path: gh-pages - - - name: Allure Report action from marketplace - uses: simple-elf/allure-report-action@master - if: success() - id: allure-report - with: - gh_pages: gh-pages - allure_results: allure - allure_report: allure-report - allure_history: allure-history - keep_reports: 20 - - - name: Deploy report to Github Pages - if: success() - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_branch: gh-pages - publish_dir: allure-history - - - name: Comment PR with the Test Results - if: success() - uses: mshick/add-pr-comment@v2 - with: - message: | - UI Automated Tests execution is complete! You can find the test results report [here](https://satellite-im.github.io/testing-uplink/${{ github.run_number }}) - remove-artifacts: needs: [ build-mac, - build-windows, test-mac, - test-mac-chats, - test-windows-chats, - test-windows, - publish-test-results, + test-mac-chats ] runs-on: ubuntu-latest @@ -744,17 +334,11 @@ jobs: uses: geekyeggo/delete-artifact@v2 with: name: | - Uplink-windows-latest - uplink-windows-assets Uplink-macos-latest test-report-macos-ci test-report-macos-chatA test-report-macos-chatB - test-report-windows-ci - test-report-windows-chats test-allure-mac-ci test-allure-mac-chatA test-allure-mac-chatB - test-allure-windows-ci - test-allure-windows-chats test-accounts diff --git a/.github/workflows/ui-automated-windows.yml b/.github/workflows/ui-automated-windows.yml new file mode 100644 index 00000000000..7063ce1e822 --- /dev/null +++ b/.github/workflows/ui-automated-windows.yml @@ -0,0 +1,456 @@ +name: UI Tests on Windows only ๐Ÿงช + +on: + schedule: + - cron: "0 0/6 * * 1-5" + pull_request: + types: [opened, synchronize, reopened, edited] + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CARGO_TERM_COLOR: always + +jobs: + build-windows: + runs-on: + labels: windows-latest + + steps: + - name: Checkout testing directory ๐Ÿ”– + uses: actions/checkout@v3 + with: + repository: Satellite-im/Uplink + + - name: Install Rust ๐Ÿ’ฟ + uses: actions-rs/toolchain@v1 + with: + toolchain: 1.70.0 + override: true + components: rustfmt, clippy + + - name: Build executable ๐Ÿ–ฅ๏ธ + run: cargo build --release -F production_mode + continue-on-error: true + + - name: Create ZIP archive on Windows ๐Ÿ—ณ๏ธ + run: Compress-Archive -Path target/release/uplink.exe -Destination uplinkWindows.zip + + - name: Copy Extensions ๐Ÿ—ณ๏ธ + run: | + mkdir ./ui/extra/extensions + cp -r ./target/release/emoji_selector.d ./ui/extra/extensions/ + cp -r ./target/release/emoji_selector.dll ./ui/extra/extensions/ + cp -r ./target/release/emoji_selector.dll.exp ./ui/extra/extensions/ + cp -r ./target/release/emoji_selector.dll.lib ./ui/extra/extensions/ + cp -r ./target/release/emoji_selector.pdb ./ui/extra/extensions/ + + - name: Upload Executable โฌ†๏ธ + uses: actions/upload-artifact@v3 + with: + name: Uplink-windows-latest + path: uplinkWindows.zip + + - name: Upload Windows Assets + uses: actions/upload-artifact@v3 + with: + name: uplink-windows-assets + path: | + ui/extra/images/ + ui/extra/prism_langs/ + ui/extra/themes/ + ui/extra/extensions/ + + - name: Add label if any of build jobs failed + if: failure() + uses: buildsville/add-remove-label@v2.0.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + labels: | + Failed Automated Test + type: add + + test-windows-chats: + needs: build-windows + runs-on: windows-latest + + steps: + - name: Checkout testing directory ๐Ÿ”– + uses: actions/checkout@v3 + + - name: Change resolution on Windows Runner + run: Set-DisplayResolution -Width 1920 -Height 1080 -Force + shell: powershell + + - name: Download the Windows app ๐Ÿ—ณ๏ธ + uses: actions/download-artifact@v3 + with: + name: Uplink-windows-latest + path: ./apps + + - name: Extract .zip into apps Directory ๐Ÿ—ณ๏ธ + run: Expand-Archive -Path ./apps/uplinkWindows.zip -DestinationPath ./apps + + - name: Download the Windows app assets + uses: actions/download-artifact@v3 + with: + name: uplink-windows-assets + path: ./apps + + - name: Copy app to have two instances ๐Ÿ’ฟ + working-directory: ./apps + run: | + cp -r ./uplink.exe ./uplink2.exe + + - name: Move Windows assets to correct locations ๐Ÿ’ฟ + working-directory: ./apps + run: | + mkdir ./bin/extra + mkdir ./extra + mv ./uplink.exe ./bin/ + mv ./uplink2.exe ./bin/ + mv ./images/ ./bin/extra/ + mv ./prism_langs/ ./bin/extra/ + mv ./themes/ ./extra/ + + - name: Setup Node.js ๐Ÿ”จ + uses: actions/setup-node@v3 + with: + node-version: 18 + cache: "npm" + + - name: Cache NPM dependencies ๐Ÿ”จ + uses: actions/cache@v3 + id: cache-windows-chats + with: + path: node_modules + key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }} + + - name: Install NPM dependencies ๐Ÿ“ฆ + if: steps.cache-windows-chats.outputs.cache-hit != 'true' + run: npm ci + + - name: Install Appium Server ๐Ÿ’ป + run: | + npm install -g appium@next + appium -v + + - name: Install Appium Driver ๐Ÿ’ป + run: | + appium driver install --source=npm appium-windows-driver + appium driver list + + - name: Setup FFMPEG to record screen + uses: FedericoCarboni/setup-ffmpeg@v2 + id: setup-ffmpeg + + - name: Delete Cache Folder if exists - Windows + run: If (Test-Path $home/.uplink/.user) {Remove-Item -Recurse -Force $home/.uplink/.user} Else { Break } + shell: powershell + + - name: Run Chat Tests on Windows ๐Ÿงช + run: npm run windows.multiremote + + - name: Upload Test Report - Windows Chats + if: always() + uses: actions/upload-artifact@v3 + with: + name: test-report-windows-chats + path: ./test-report/*.xml + + - name: Upload Allure Test Results + if: always() + uses: actions/upload-artifact@v3 + with: + name: test-allure-windows-chats + path: ./allure-results/ + + - name: Upload Screenshots for Windows - Chats ๐Ÿ“ท + uses: actions/upload-artifact@v3 + if: failure() + with: + name: appium-screenshots-windows-chats + path: ./test-results + + - name: Upload Appium Log for Windows - Chats ๐Ÿ“ท + uses: actions/upload-artifact@v3 + if: failure() + with: + name: appium-log-windows-chats + path: | + ./appium.log + + - name: Add label if any of test jobs failed + if: failure() + uses: buildsville/add-remove-label@v2.0.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + labels: | + Failed Automated Test + type: add + + test-windows: + needs: build-windows + runs-on: windows-latest + + steps: + - name: Checkout testing directory ๐Ÿ”– + uses: actions/checkout@v3 + + - name: Change resolution on Windows Runner + run: Set-DisplayResolution -Width 1920 -Height 1080 -Force + shell: powershell + + - name: Download the Windows app ๐Ÿ—ณ๏ธ + uses: actions/download-artifact@v3 + with: + name: Uplink-windows-latest + path: ./apps + + - name: Extract .zip into apps Directory ๐Ÿ—ณ๏ธ + run: Expand-Archive -Path ./apps/uplinkWindows.zip -DestinationPath ./apps + + - name: Download the Windows app assets + uses: actions/download-artifact@v3 + with: + name: uplink-windows-assets + path: ./apps + + - name: Move Windows assets to correct locations ๐Ÿ’ฟ + working-directory: ./apps + run: | + mkdir ./bin/extra + mkdir ./extra + mv ./uplink.exe ./bin/ + mv ./images/ ./bin/extra/ + mv ./prism_langs/ ./bin/extra/ + mv ./themes/ ./extra/ + + - name: Setup Node.js ๐Ÿ”จ + uses: actions/setup-node@v3 + with: + node-version: 18 + cache: "npm" + + - name: Cache NPM dependencies ๐Ÿ”จ + uses: actions/cache@v3 + id: cache-windows + with: + path: node_modules + key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }} + + - name: Install NPM dependencies ๐Ÿ“ฆ + if: steps.cache-windows.outputs.cache-hit != 'true' + run: npm ci + + - name: Install and Run Appium Server ๐Ÿ’ป + run: | + npm install -g appium@next + appium -v + + - name: Install Appium Driver ๐Ÿ’ป + run: | + appium driver install --source=npm appium-windows-driver + appium driver list + + - name: Setup FFMPEG to record screen + uses: FedericoCarboni/setup-ffmpeg@v2 + id: setup-ffmpeg + + - name: Delete Cache Folder if exists - Windows + run: If (Test-Path $home/.uplink/.user) {Remove-Item -Recurse -Force $home/.uplink/.user} Else { Break } + shell: powershell + + - name: Run Tests on Windows ๐Ÿงช + id: test-execution-windows + run: npm run windows.ci + + - name: Upload Test Report - Windows CI + if: always() + uses: actions/upload-artifact@v3 + with: + name: test-report-windows-ci + path: ./test-report/*.xml + + - name: Upload Allure Test Results + if: always() + uses: actions/upload-artifact@v3 + with: + name: test-allure-windows-ci + path: ./allure-results/ + + - name: Upload Screenshots for Windows ๐Ÿ“ท + uses: actions/upload-artifact@v3 + if: failure() + with: + name: appium-screenshots-windows + path: ./test-results + + - name: Upload Appium Log for Windows ๐Ÿ“ท + uses: actions/upload-artifact@v3 + if: failure() + with: + name: appium-log-windows + path: ./appium.log + + - name: Add label if any of test jobs failed + if: failure() + uses: buildsville/add-remove-label@v2.0.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + labels: | + Failed Automated Test + type: add + + publish-test-results: + if: always() + needs: + #[build-mac, build-windows, test-mac, test-mac-chats, test-windows-chats, test-windows] + [build-windows, test-windows-chats, test-windows] + runs-on: ubuntu-latest + permissions: + checks: write + pull-requests: write + contents: write + issues: read + + steps: + #- name: Download Test Report for MacOS CI + # uses: actions/download-artifact@v3 + # with: + # name: test-report-macos-ci + # path: artifacts + + #- name: Download Test Report for MacOS Chat A + # uses: actions/download-artifact@v3 + # with: + # name: test-report-macos-chatA + # path: artifacts + + #- name: Download Test Report for MacOS Chat B + # uses: actions/download-artifact@v3 + # with: + # name: test-report-macos-chatB + # path: artifacts + + - name: Download Test Report for Windows Chats + uses: actions/download-artifact@v3 + with: + name: test-report-windows-chats + path: artifacts + + - name: Download Test Report for Windows CI + uses: actions/download-artifact@v3 + with: + name: test-report-windows-ci + path: artifacts + + #- name: Download Allure Results for MacOS CI + # uses: actions/download-artifact@v3 + # with: + # name: test-allure-mac-ci + # path: allure + + #- name: Download Allure Results for MacOS Chat A + # uses: actions/download-artifact@v3 + # with: + # name: test-allure-mac-chatA + # path: allure + + #- name: Download Allure Results for MacOS Chat B + # uses: actions/download-artifact@v3 + # with: + # name: test-allure-mac-chatB + # path: allure + + - name: Download Allure Results for Windows CI + uses: actions/download-artifact@v3 + with: + name: test-allure-windows-ci + path: allure + + - name: Download Allure Results for Windows Chats + uses: actions/download-artifact@v3 + with: + name: test-allure-windows-chats + path: allure + + - name: Publish Test Results for Tests + uses: EnricoMi/publish-unit-test-result-action/composite@v2 + if: success() + with: + junit_files: "artifacts/**/*.xml" + ignore_runs: true + job_summary: false + compare_to_earlier_commit: false + check_name: "UI Automated Test Results Summary for MacOS/Windows" + + - name: Get Allure history + uses: actions/checkout@v3 + if: success() + continue-on-error: true + with: + ref: gh-pages + path: gh-pages + + - name: Allure Report action from marketplace + uses: simple-elf/allure-report-action@master + if: success() + id: allure-report + with: + gh_pages: gh-pages + allure_results: allure + allure_report: allure-report + allure_history: allure-history + keep_reports: 20 + + - name: Deploy report to Github Pages + if: success() + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_branch: gh-pages + publish_dir: allure-history + + - name: Comment PR with the Test Results + if: success() + uses: mshick/add-pr-comment@v2 + with: + message: | + UI Automated Tests execution is complete! You can find the test results report [here](https://satellite-im.github.io/testing-uplink/${{ github.run_number }}) + + remove-artifacts: + needs: + [ + build-windows, + test-windows-chats, + test-windows, + publish-test-results, + ] + runs-on: ubuntu-latest + + steps: + - name: Checkout testing directory ๐Ÿ”– + uses: actions/checkout@v3 + + - name: Remove label if all test jobs succeeded + uses: buildsville/add-remove-label@v2.0.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + labels: | + Failed Automated Test + type: remove + + - name: Delete artifacts + uses: geekyeggo/delete-artifact@v2 + with: + name: | + Uplink-windows-latest + test-report-windows-chats + test-report-windows-ci + test-allure-windows-chats + test-allure-windows-ci diff --git a/config/wdio.mac.chatA.conf.ts b/config/wdio.mac.chatA.conf.ts index cac831eacd5..6e93a396800 100644 --- a/config/wdio.mac.chatA.conf.ts +++ b/config/wdio.mac.chatA.conf.ts @@ -55,7 +55,6 @@ export const config: WebdriverIO.Config = { platformName: "mac", "appium:automationName": MACOS_DRIVER, "appium:bundleId": MACOS_BUNDLE_ID, - "appium:arguments": ["--path", join(process.cwd() + "/tests/fixtures/users/mac2/ChatUserA")], "appium:systemPort": 4724, } }, diff --git a/config/wdio.mac.chatB.conf.ts b/config/wdio.mac.chatB.conf.ts index d9650b03d8c..a989ffc105b 100644 --- a/config/wdio.mac.chatB.conf.ts +++ b/config/wdio.mac.chatB.conf.ts @@ -55,7 +55,6 @@ export const config: WebdriverIO.Config = { platformName: "mac", "appium:automationName": MACOS_DRIVER, "appium:bundleId": MACOS_BUNDLE_ID, - "appium:arguments": ["--path", join(process.cwd() + "/tests/fixtures/users/mac2/ChatUserB")], "appium:systemPort": 4724, } }, diff --git a/config/wdio.mac.ci.conf.ts b/config/wdio.mac.ci.conf.ts index d2e98987e23..c3dce3da6a9 100644 --- a/config/wdio.mac.ci.conf.ts +++ b/config/wdio.mac.ci.conf.ts @@ -26,8 +26,11 @@ export const config: WebdriverIO.Config = { // If you are calling `wdio` from an NPM script (see https://docs.npmjs.com/cli/run-script), // then the current working directory is where your `package.json` resides, so `wdio` // will be called from there. - // - specs: [join(process.cwd(), "./tests/suites/MainTests/01-UplinkTests.suite.ts")], + maxInstances: 1, + specs: [ + [join(process.cwd(), "./tests/suites/MainTests/03-CreateAccountTests.suite.ts")], + [join(process.cwd(), "./tests/suites/MainTests/01-UplinkTests.suite.ts")] + ], // Patterns to exclude. exclude: [ // 'path/to/excluded/files' From 0a70db812f95b60e67bee31915ac7f81e8d570b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Carden=CC=83a?= <35935591+luisecm@users.noreply.github.com> Date: Tue, 31 Oct 2023 23:14:17 -0600 Subject: [PATCH 07/22] chore(appium): craete new config files for accounts --- .github/workflows/ui-automated-tests.yml | 52 +++++- .../{ => macos-chats}/wdio.mac.chatA.conf.ts | 0 .../{ => macos-chats}/wdio.mac.chatB.conf.ts | 0 .../wdio.mac.createAccountA.conf.ts | 149 ++++++++++++++++++ .../wdio.mac.createAccountB.conf.ts | 149 ++++++++++++++++++ config/wdio.mac.app.conf.ts | 3 +- config/wdio.mac.ci.conf.ts | 3 +- package.json | 6 +- ...s.spec.ts => 14-settings-messages.spec.ts} | 0 tests/specs/15-create-first-account.spec.ts | 96 +++++++++++ ...ec.ts => 16-create-second-account.spec.ts} | 46 +----- .../suites/MainTests/01-UplinkTests.suite.ts | 2 +- .../MainTests/02-UplinkWindows.suite.ts | 2 +- .../MainTests/03-CreateAccountA.suite.ts | 6 + .../MainTests/03-CreateAccountTests.suite.ts | 6 - .../MainTests/04-CreateAccountB.suite.ts | 6 + 16 files changed, 460 insertions(+), 66 deletions(-) rename config/{ => macos-chats}/wdio.mac.chatA.conf.ts (100%) rename config/{ => macos-chats}/wdio.mac.chatB.conf.ts (100%) create mode 100644 config/macos-chats/wdio.mac.createAccountA.conf.ts create mode 100644 config/macos-chats/wdio.mac.createAccountB.conf.ts rename tests/specs/{15-settings-messages.spec.ts => 14-settings-messages.spec.ts} (100%) create mode 100644 tests/specs/15-create-first-account.spec.ts rename tests/specs/{14-create-reusable-accounts.spec.ts => 16-create-second-account.spec.ts} (67%) create mode 100644 tests/suites/MainTests/03-CreateAccountA.suite.ts delete mode 100644 tests/suites/MainTests/03-CreateAccountTests.suite.ts create mode 100644 tests/suites/MainTests/04-CreateAccountB.suite.ts diff --git a/.github/workflows/ui-automated-tests.yml b/.github/workflows/ui-automated-tests.yml index f5b2e77781b..77058fbae6e 100644 --- a/.github/workflows/ui-automated-tests.yml +++ b/.github/workflows/ui-automated-tests.yml @@ -164,13 +164,44 @@ jobs: with: name: appium-log-macos path: ./appium.log + + - name: Run Tests on to Create First Account ๐Ÿงช + run: npm run mac.createAccountA - - name: Upload test accounts for Chat + - name: Delete data from Friends Tests for artifact of Chat User A + working-directory: ./tests/fixtures/users/mac2/ + run: rm -rf ./FriendsTestUser/ + + - name: List all of the files extracted on Repo After First Account Created + run: | + pwd + ls -R + + - name: Upload test accounts for Chat User A + uses: actions/upload-artifact@v3 + if: always() + with: + name: account-first-user + path: ./tests/fixtures/users/mac2/ + + - name: Run Tests on to Create Second Account ๐Ÿงช + run: npm run mac.createAccountB + + - name: Delete data from Friends Tests for artifact of Chat User B + working-directory: ./tests/fixtures/users/mac2/ + run: rm -rf ./FriendsTestUser/ + + - name: List all of the files extracted on Repo After Second Account Created + run: | + pwd + ls -R + + - name: Upload test accounts for Chat User B uses: actions/upload-artifact@v3 if: always() with: - name: test-accounts - path: ./tests/fixtures/users/ + name: account-second-user + path: ./tests/fixtures/users/mac2/ - name: Add label if any of test jobs failed if: failure() @@ -203,11 +234,17 @@ jobs: name: Uplink-macos-latest path: ./apps - - name: Download Test User Accounts ๐Ÿ—ณ๏ธ + - name: Download Test User Account User A ๐Ÿ—ณ๏ธ + uses: actions/download-artifact@v3 + with: + name: account-first-user + path: ./tests/fixtures/users/mac2/ + + - name: Download Test User Account User A ๐Ÿ—ณ๏ธ uses: actions/download-artifact@v3 with: - name: test-accounts - path: ./tests/fixtures/users/ + name: account-second-user + path: ./tests/fixtures/users/mac2/ - name: List all of the files extracted run: | @@ -341,4 +378,5 @@ jobs: test-allure-mac-ci test-allure-mac-chatA test-allure-mac-chatB - test-accounts + account-first-user + account-second-user diff --git a/config/wdio.mac.chatA.conf.ts b/config/macos-chats/wdio.mac.chatA.conf.ts similarity index 100% rename from config/wdio.mac.chatA.conf.ts rename to config/macos-chats/wdio.mac.chatA.conf.ts diff --git a/config/wdio.mac.chatB.conf.ts b/config/macos-chats/wdio.mac.chatB.conf.ts similarity index 100% rename from config/wdio.mac.chatB.conf.ts rename to config/macos-chats/wdio.mac.chatB.conf.ts diff --git a/config/macos-chats/wdio.mac.createAccountA.conf.ts b/config/macos-chats/wdio.mac.createAccountA.conf.ts new file mode 100644 index 00000000000..368ff02c6a9 --- /dev/null +++ b/config/macos-chats/wdio.mac.createAccountA.conf.ts @@ -0,0 +1,149 @@ +import "module-alias/register"; +import allureReporter from '@wdio/allure-reporter' +import { config as sharedConfig } from '@config/wdio.shared.conf'; +import { homedir } from "os"; +import { join } from "path"; +import { MACOS_BUNDLE_ID, MACOS_DRIVER } from "@helpers/constants"; +const fsp = require("fs").promises; +const { readFileSync, rmSync } = require("fs"); + +// @ts-expect-error +export const config: WebdriverIO.Config = { + ...sharedConfig, + ...{ + // + // ================== + // Specify Test Files + // ================== + // Define which test specs should run. The pattern is relative to the directory + // from which `wdio` was called. + // + // The specs are defined as an array of spec files (optionally using wildcards + // that will be expanded). The test for each spec file will be run in a separate + // worker process. In order to have a group of spec files run in the same worker + // process simply enclose them in an array within the specs array. + // + // If you are calling `wdio` from an NPM script (see https://docs.npmjs.com/cli/run-script), + // then the current working directory is where your `package.json` resides, so `wdio` + // will be called from there. + // + maxInstances: 1, + specs: [ + join(process.cwd(), "./tests/suites/MainTests/03-CreateAccountA.suite.ts") + ], + // Patterns to exclude. + exclude: [ + // 'path/to/excluded/files' + ], + // + // ============ + // Capabilities + // ============ + // Define your capabilities here. WebdriverIO can run multiple capabilities at the same + // time. Depending on the number of capabilities, WebdriverIO launches several test + // sessions. Within your capabilities you can overwrite the spec and exclude options in + // order to group specific specs to a specific capability. + // + // + // If you have trouble getting all important capabilities together, check out the + // Sauce Labs platform configurator - a great tool to configure your capabilities: + // https://docs.saucelabs.com/reference/platforms-configurator + // + port: 4723, + path: '/', + capabilities: { + userA: { + capabilities: { + platformName: "mac", + "appium:automationName": MACOS_DRIVER, + "appium:bundleId": MACOS_BUNDLE_ID, + "appium:arguments": ["--path", homedir() + "/.uplink"], + "appium:systemPort": 4724, + "appium:prerun": { + command: 'do shell script "rm -rf ~/.uplink"', + }, + } + }, + } + , + // + // =================== + // Test Configurations + // =================== + // Define all options that are relevant for the WebdriverIO instance here + // + reporters: [ + ["spec", + { + showPreface: false, + }, + ], + ['allure', + { + outputDir: './allure-results', + disableWebdriverStepsReporting: true, + disableWebdriverScreenshotsReporting: false, + } + ], + ['junit', + { + outputDir: './test-report/', + outputFileFormat: function (options) { + return `test-results-macos-app-${options.cid}.xml`; + } + } + ], + ], + // + // ===== + // Hooks + // ===== + // WebdriverIO provides several hooks you can use to interfere with the test process in order to enhance + // it and to build services around it. You can either apply a single function or an array of + // methods to it. If one of them returns with a promise, WebdriverIO will wait until that promise got + // resolved to continue. + onPrepare: async function() { + const cacheFolder = homedir() + "/.uplink/.user"; + const allureResultsFolder = join(process.cwd(), "./allure-results"); + const testReportFolder = join(process.cwd(), "./test-report"); + const testResultsFolder = join(process.cwd(), "./test-results"); + try { + await rmSync(allureResultsFolder, { recursive: true, force: true }); + await rmSync(testReportFolder, { recursive: true, force: true }); + await rmSync(testResultsFolder, { recursive: true, force: true }); + console.log("Deleted Artifacts Folders Successfully!"); + } catch (error) { + console.error( + `Got an error trying to delete artifacts folders: ${error.message}` + ); + } + try { + await rmSync(cacheFolder, { recursive: true, force: true }); + console.log("Deleted Cache Folder Successfully!"); + } catch (error) { + console.error( + `Got an error trying to delete Cache Folder: ${error.message}` + ); + } + }, + + afterTest: async function (test, describe, { error }) { + if (error) { + let imageFile = await driver.takeScreenshot(); + const imageFolder = join(process.cwd(), "./test-results/macos-app", test.parent); + const imageTitle = test.title + " - Failed.png" + await fsp.mkdir(imageFolder, {recursive: true}); + await fsp.writeFile( + imageFolder + "/" + imageTitle, + imageFile, + "base64" + ); + + // Add to Screenshot to Allure Reporter + const data = await readFileSync(`${imageFolder}/${imageTitle}`); + allureReporter.addAttachment(imageTitle, data, 'image/png') + } + }, + } + +} \ No newline at end of file diff --git a/config/macos-chats/wdio.mac.createAccountB.conf.ts b/config/macos-chats/wdio.mac.createAccountB.conf.ts new file mode 100644 index 00000000000..42b4b93293e --- /dev/null +++ b/config/macos-chats/wdio.mac.createAccountB.conf.ts @@ -0,0 +1,149 @@ +import "module-alias/register"; +import allureReporter from '@wdio/allure-reporter' +import { config as sharedConfig } from '@config/wdio.shared.conf'; +import { homedir } from "os"; +import { join } from "path"; +import { MACOS_BUNDLE_ID, MACOS_DRIVER } from "@helpers/constants"; +const fsp = require("fs").promises; +const { readFileSync, rmSync } = require("fs"); + +// @ts-expect-error +export const config: WebdriverIO.Config = { + ...sharedConfig, + ...{ + // + // ================== + // Specify Test Files + // ================== + // Define which test specs should run. The pattern is relative to the directory + // from which `wdio` was called. + // + // The specs are defined as an array of spec files (optionally using wildcards + // that will be expanded). The test for each spec file will be run in a separate + // worker process. In order to have a group of spec files run in the same worker + // process simply enclose them in an array within the specs array. + // + // If you are calling `wdio` from an NPM script (see https://docs.npmjs.com/cli/run-script), + // then the current working directory is where your `package.json` resides, so `wdio` + // will be called from there. + // + maxInstances: 1, + specs: [ + join(process.cwd(), "./tests/suites/MainTests/04-CreateAccountB.suite.ts") + ], + // Patterns to exclude. + exclude: [ + // 'path/to/excluded/files' + ], + // + // ============ + // Capabilities + // ============ + // Define your capabilities here. WebdriverIO can run multiple capabilities at the same + // time. Depending on the number of capabilities, WebdriverIO launches several test + // sessions. Within your capabilities you can overwrite the spec and exclude options in + // order to group specific specs to a specific capability. + // + // + // If you have trouble getting all important capabilities together, check out the + // Sauce Labs platform configurator - a great tool to configure your capabilities: + // https://docs.saucelabs.com/reference/platforms-configurator + // + port: 4723, + path: '/', + capabilities: { + userA: { + capabilities: { + platformName: "mac", + "appium:automationName": MACOS_DRIVER, + "appium:bundleId": MACOS_BUNDLE_ID, + "appium:arguments": ["--path", homedir() + "/.uplink"], + "appium:systemPort": 4724, + "appium:prerun": { + command: 'do shell script "rm -rf ~/.uplink"', + }, + } + }, + } + , + // + // =================== + // Test Configurations + // =================== + // Define all options that are relevant for the WebdriverIO instance here + // + reporters: [ + ["spec", + { + showPreface: false, + }, + ], + ['allure', + { + outputDir: './allure-results', + disableWebdriverStepsReporting: true, + disableWebdriverScreenshotsReporting: false, + } + ], + ['junit', + { + outputDir: './test-report/', + outputFileFormat: function (options) { + return `test-results-macos-app-${options.cid}.xml`; + } + } + ], + ], + // + // ===== + // Hooks + // ===== + // WebdriverIO provides several hooks you can use to interfere with the test process in order to enhance + // it and to build services around it. You can either apply a single function or an array of + // methods to it. If one of them returns with a promise, WebdriverIO will wait until that promise got + // resolved to continue. + onPrepare: async function() { + const cacheFolder = homedir() + "/.uplink/.user"; + const allureResultsFolder = join(process.cwd(), "./allure-results"); + const testReportFolder = join(process.cwd(), "./test-report"); + const testResultsFolder = join(process.cwd(), "./test-results"); + try { + await rmSync(allureResultsFolder, { recursive: true, force: true }); + await rmSync(testReportFolder, { recursive: true, force: true }); + await rmSync(testResultsFolder, { recursive: true, force: true }); + console.log("Deleted Artifacts Folders Successfully!"); + } catch (error) { + console.error( + `Got an error trying to delete artifacts folders: ${error.message}` + ); + } + try { + await rmSync(cacheFolder, { recursive: true, force: true }); + console.log("Deleted Cache Folder Successfully!"); + } catch (error) { + console.error( + `Got an error trying to delete Cache Folder: ${error.message}` + ); + } + }, + + afterTest: async function (test, describe, { error }) { + if (error) { + let imageFile = await driver.takeScreenshot(); + const imageFolder = join(process.cwd(), "./test-results/macos-app", test.parent); + const imageTitle = test.title + " - Failed.png" + await fsp.mkdir(imageFolder, {recursive: true}); + await fsp.writeFile( + imageFolder + "/" + imageTitle, + imageFile, + "base64" + ); + + // Add to Screenshot to Allure Reporter + const data = await readFileSync(`${imageFolder}/${imageTitle}`); + allureReporter.addAttachment(imageTitle, data, 'image/png') + } + }, + } + +} \ No newline at end of file diff --git a/config/wdio.mac.app.conf.ts b/config/wdio.mac.app.conf.ts index 6f5eb064412..c2275f3c725 100644 --- a/config/wdio.mac.app.conf.ts +++ b/config/wdio.mac.app.conf.ts @@ -29,8 +29,7 @@ export const config: WebdriverIO.Config = { // maxInstances: 1, specs: [ - [join(process.cwd(), "./tests/suites/MainTests/03-CreateAccountTests.suite.ts")], - [join(process.cwd(), "./tests/suites/MainTests/01-UplinkTests.suite.ts")] + join(process.cwd(), "./tests/suites/MainTests/01-UplinkTests.suite.ts") ], // Patterns to exclude. exclude: [ diff --git a/config/wdio.mac.ci.conf.ts b/config/wdio.mac.ci.conf.ts index c3dce3da6a9..a19be70ae96 100644 --- a/config/wdio.mac.ci.conf.ts +++ b/config/wdio.mac.ci.conf.ts @@ -28,8 +28,7 @@ export const config: WebdriverIO.Config = { // will be called from there. maxInstances: 1, specs: [ - [join(process.cwd(), "./tests/suites/MainTests/03-CreateAccountTests.suite.ts")], - [join(process.cwd(), "./tests/suites/MainTests/01-UplinkTests.suite.ts")] + join(process.cwd(), "./tests/suites/MainTests/01-UplinkTests.suite.ts") ], // Patterns to exclude. exclude: [ diff --git a/package.json b/package.json index 20459a6fbaf..a63bd7a3cd4 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,10 @@ "description": "An automation testing framework built with WebdriverIO and Appium to test Uplink Desktop app", "scripts": { "mac.app": "wdio config/wdio.mac.app.conf.ts", - "mac.chatA": "wdio config/wdio.mac.chatA.conf.ts", - "mac.chatB": "wdio config/wdio.mac.chatB.conf.ts", + "mac.chatA": "wdio config/macos-chats/wdio.mac.chatA.conf.ts", + "mac.chatB": "wdio config/macos-chats/wdio.mac.chatB.conf.ts", + "mac.createAccountA": "wdio config/macos-chats/wdio.mac.createAccountA.conf.ts", + "mac.createAccountB": "wdio config/macos-chats/wdio.mac.createAccountB.conf.ts", "mac.ci": "wdio config/wdio.mac.ci.conf.ts", "mac.multiremote": "wdio config/wdio.mac.multiremote.conf.ts", "windows.app": "wdio config/wdio.windows.app.conf.ts", diff --git a/tests/specs/15-settings-messages.spec.ts b/tests/specs/14-settings-messages.spec.ts similarity index 100% rename from tests/specs/15-settings-messages.spec.ts rename to tests/specs/14-settings-messages.spec.ts diff --git a/tests/specs/15-create-first-account.spec.ts b/tests/specs/15-create-first-account.spec.ts new file mode 100644 index 00000000000..b99536dd415 --- /dev/null +++ b/tests/specs/15-create-first-account.spec.ts @@ -0,0 +1,96 @@ +import "module-alias/register"; +import { grabCacheFolder, maximizeWindow, saveTestKeys } from "@helpers/commands"; +import { USER_A_INSTANCE } from "@helpers/constants"; +import CreatePinScreen from "@screenobjects/account-creation/CreatePinScreen"; +import CreateUserScreen from "@screenobjects/account-creation/CreateUserScreen"; +import SettingsProfileScreen from "@screenobjects/settings/SettingsProfileScreen"; +import WelcomeScreen from "@screenobjects/welcome-screen/WelcomeScreen"; +let createPinFirstUser = new CreatePinScreen(USER_A_INSTANCE); +let createUserFirstUser = new CreateUserScreen(USER_A_INSTANCE); +let settingsProfileFirstUser = new SettingsProfileScreen(USER_A_INSTANCE); +let welcomeScreenFirstUser = new WelcomeScreen(USER_A_INSTANCE); + +export default async function createFirstAccount() { + it("Validate warning texts are displayed on screen", async () => { + const unlockWarningHeader = await createPinFirstUser.unlockWarningHeader; + await unlockWarningHeader.waitForExist(); + await expect(unlockWarningHeader).toHaveTextContaining([ + "LET'S CHOOSE YOUR PASSWORD", + "WELCOME BACK,", + ]); + + const unlockWarningParagraph = + await createPinFirstUser.unlockWarningParagraph; + await unlockWarningParagraph.waitForExist(); + await expect(unlockWarningParagraph).toHaveTextContaining( + "(this is used to encrypt all of the data Uplink stores on your computer when you're not using it so nobody can read your data.)" + ); + }); + + it("Unlock Screen - Reset Account is shown after right clicking on Help Button", async () => { + // Right click on Help Button to show the help menu + await createPinFirstUser.openHelpButtonMenu(); + + // Right click again on Help Button to hide the help menu + await createPinFirstUser.openHelpButtonMenu(); + }); + + it("Enter a valid pin and continue creating a username", async () => { + await createPinFirstUser.enterPin("1234"); + const statusOfButton = + await createPinFirstUser.getStatusOfCreateAccountButton(); + await expect(statusOfButton).toEqual("true"); + await createPinFirstUser.clickOnCreateAccount(); + await createUserFirstUser.waitForIsShown(true); + }); + + it("Enter valid username to continue", async () => { + await createUserFirstUser.enterUsername("ChatUserA"); + const statusOfButton = + await createPinFirstUser.getStatusOfCreateAccountButton(); + await expect(statusOfButton).toEqual("true"); + await createUserFirstUser.clickOnCreateAccount(); + await welcomeScreenFirstUser.waitForIsShown(true); + + // Maximize Window on Execution + await maximizeWindow(USER_A_INSTANCE); + }); + + it("Go to Settings with Chat User B", async () => { + // Go to Settings Screen and select the Settings Screen to validate + await welcomeScreenFirstUser.goToSettings(); + await settingsProfileFirstUser.waitForIsShown(true); + }); + + it("Settings Profile - Click On Copy ID Button", async () => { + // Wait for toast notification to be closed before starting test + await settingsProfileFirstUser.waitUntilNotificationIsClosed(); + + // Click on Copy ID button and assert Toast Notification is displayed + await settingsProfileFirstUser.clickOnCopyIDButton(); + + // Wait for toast notification to be closed + await settingsProfileFirstUser.waitUntilNotificationIsClosed(); + }); + + it("Settings Profile - Copied ID can be placed on any text field", async () => { + // Paste copied DID Key into Status Input + await settingsProfileFirstUser.pasteUserKeyInStatus(); + + // Ensure that value placed in Status is the did key from the user + const statusInputText = + await settingsProfileFirstUser.getStatusInputElement(); + await expect(statusInputText).toHaveTextContaining("did:key:"); + + const didkey = await settingsProfileFirstUser.getCopiedDidFromStatusInput(); + const username = "ChatUserA"; + // Grab cache folder and restart + await saveTestKeys(username, didkey, USER_A_INSTANCE); + + // Update banner picture from user A + await grabCacheFolder(username, USER_A_INSTANCE); + + // Clear value from status input + await settingsProfileFirstUser.deleteStatus(); + }); +} diff --git a/tests/specs/14-create-reusable-accounts.spec.ts b/tests/specs/16-create-second-account.spec.ts similarity index 67% rename from tests/specs/14-create-reusable-accounts.spec.ts rename to tests/specs/16-create-second-account.spec.ts index 60625859d90..ed71236ad29 100644 --- a/tests/specs/14-create-reusable-accounts.spec.ts +++ b/tests/specs/16-create-second-account.spec.ts @@ -3,12 +3,10 @@ import { grabCacheFolder, maximizeWindow, saveTestKeys } from "@helpers/commands import { USER_A_INSTANCE } from "@helpers/constants"; import CreatePinScreen from "@screenobjects/account-creation/CreatePinScreen"; import CreateUserScreen from "@screenobjects/account-creation/CreateUserScreen"; -import CropImageProfileModal from "@screenobjects/settings/CropToolProfileModal"; import SettingsProfileScreen from "@screenobjects/settings/SettingsProfileScreen"; import WelcomeScreen from "@screenobjects/welcome-screen/WelcomeScreen"; let createPinFirstUser = new CreatePinScreen(USER_A_INSTANCE); let createUserFirstUser = new CreateUserScreen(USER_A_INSTANCE); -let cropProfileFirstUser = new CropImageProfileModal(USER_A_INSTANCE); let settingsProfileFirstUser = new SettingsProfileScreen(USER_A_INSTANCE); let welcomeScreenFirstUser = new WelcomeScreen(USER_A_INSTANCE); @@ -64,48 +62,6 @@ export default async function createSecondAccount() { await settingsProfileFirstUser.waitForIsShown(true); }); - it("Settings Profile - Profile Picture - Crop Image and add profile picture", async () => { - // Click on profile picture upload button and select the file logo.jpg - await settingsProfileFirstUser.selectProfilePicture( - "./tests/fixtures/logo.jpg" - ); - - // Validate Crop Tool Modal is displayed - await cropProfileFirstUser.validateCropToolModalIsShown(); - - // Click three times on increase button, then one time on decrease button - await cropProfileFirstUser.clickMultipleTimesIncreaseButton(3); - await cropProfileFirstUser.clickOnDecreaseRangeButton(); - - // Validate final value shown for zoom slider is 1 - const rangeValueText = await cropProfileFirstUser.cropImageRangeValueText; - await expect(rangeValueText).toHaveTextContaining("1.2"); - - // Click on confirm button to save - await cropProfileFirstUser.clickOnConfirmButton(); - - // Validate new profile picture is displayed - await settingsProfileFirstUser.validateProfilePictureIsShown(); - }); - - // Needs visual validation steps to ensure that picture was actually loaded matches with expected image - it("Settings Profile - Crop banner and add banner picture", async () => { - // Click on banner picture upload button and select the file banner.jpg - await settingsProfileFirstUser.selectBannerPicture( - "./tests/fixtures/banner.jpg" - ); - - // Validate Crop Tool Modal is displayed - await cropProfileFirstUser.validateCropToolModalIsShown(); - - // Change the size of picture and click on confirm button to save - await cropProfileFirstUser.clickOnIncreaseRangeButton(); - await cropProfileFirstUser.clickOnConfirmButton(); - - // Validate new banner picture is displayed - await settingsProfileFirstUser.validateBannerPictureIsShown(); - }); - it("Settings Profile - Click On Copy ID Button", async () => { // Wait for toast notification to be closed before starting test await settingsProfileFirstUser.waitUntilNotificationIsClosed(); @@ -127,7 +83,7 @@ export default async function createSecondAccount() { await expect(statusInputText).toHaveTextContaining("did:key:"); const didkey = await settingsProfileFirstUser.getCopiedDidFromStatusInput(); - const username = "ChatUserA"; + const username = "ChatUserB"; // Grab cache folder and restart await saveTestKeys(username, didkey, USER_A_INSTANCE); diff --git a/tests/suites/MainTests/01-UplinkTests.suite.ts b/tests/suites/MainTests/01-UplinkTests.suite.ts index a0c3211f069..3551f1fcdc6 100644 --- a/tests/suites/MainTests/01-UplinkTests.suite.ts +++ b/tests/suites/MainTests/01-UplinkTests.suite.ts @@ -4,7 +4,7 @@ import chats from "@specs/02-chats.spec"; import files from "@specs/03-files.spec"; import settingsProfile from "@specs/05-settings-profile.spec"; import settingsGeneral from "@specs/06-settings-general.spec"; -import settingsMessages from "@specs/15-settings-messages.spec"; +import settingsMessages from "@specs/14-settings-messages.spec"; import settingsAudio from "@specs/07-settings-audio.spec"; import settingsExtensions from "@specs/08-settings-extensions.spec"; import settingsNotifications from "@specs/09-settings-notifications.spec"; diff --git a/tests/suites/MainTests/02-UplinkWindows.suite.ts b/tests/suites/MainTests/02-UplinkWindows.suite.ts index 2e2fbe372c3..f6221cd143a 100644 --- a/tests/suites/MainTests/02-UplinkWindows.suite.ts +++ b/tests/suites/MainTests/02-UplinkWindows.suite.ts @@ -4,7 +4,7 @@ import chats from "@specs/02-chats.spec"; import files from "@specs/03-files.spec"; import settingsProfile from "@specs/05-settings-profile.spec"; import settingsGeneral from "@specs/06-settings-general.spec"; -import settingsMessages from "@specs/15-settings-messages.spec"; +import settingsMessages from "@specs/14-settings-messages.spec"; import settingsAudio from "@specs/07-settings-audio.spec"; import settingsExtensions from "@specs/08-settings-extensions.spec"; import settingsNotifications from "@specs/09-settings-notifications.spec"; diff --git a/tests/suites/MainTests/03-CreateAccountA.suite.ts b/tests/suites/MainTests/03-CreateAccountA.suite.ts new file mode 100644 index 00000000000..693ca9df40a --- /dev/null +++ b/tests/suites/MainTests/03-CreateAccountA.suite.ts @@ -0,0 +1,6 @@ +import "module-alias/register"; +import createFirstAccount from "@specs/15-create-first-account.spec"; + +describe("MacOS Tests - Create First Account", function () { + describe("Create and Save First Account", createFirstAccount.bind(this)); +}) \ No newline at end of file diff --git a/tests/suites/MainTests/03-CreateAccountTests.suite.ts b/tests/suites/MainTests/03-CreateAccountTests.suite.ts deleted file mode 100644 index 44e4e7f876e..00000000000 --- a/tests/suites/MainTests/03-CreateAccountTests.suite.ts +++ /dev/null @@ -1,6 +0,0 @@ -import "module-alias/register"; -import createSecondAccount from "@specs/14-create-reusable-accounts.spec"; - -describe("MacOS Tests - Create Second Account", function () { - describe("Create Pin and Account Tests", createSecondAccount.bind(this)); -}) \ No newline at end of file diff --git a/tests/suites/MainTests/04-CreateAccountB.suite.ts b/tests/suites/MainTests/04-CreateAccountB.suite.ts new file mode 100644 index 00000000000..aae56d8c8bb --- /dev/null +++ b/tests/suites/MainTests/04-CreateAccountB.suite.ts @@ -0,0 +1,6 @@ +import "module-alias/register"; +import createSecondAccount from "@specs/16-create-second-account.spec"; + +describe("MacOS Tests - Create Second Account", function () { + describe("Create and Save Second Account", createSecondAccount.bind(this)); +}) \ No newline at end of file From 3817afeab2c452cbcf04744912105700dff29329 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Carden=CC=83a?= <35935591+luisecm@users.noreply.github.com> Date: Wed, 1 Nov 2023 00:15:28 -0600 Subject: [PATCH 08/22] chore(appium): ensure accounts are extracted --- .github/workflows/ui-automated-tests.yml | 47 ++++++------------------ 1 file changed, 12 insertions(+), 35 deletions(-) diff --git a/.github/workflows/ui-automated-tests.yml b/.github/workflows/ui-automated-tests.yml index 77058fbae6e..ed23da245f7 100644 --- a/.github/workflows/ui-automated-tests.yml +++ b/.github/workflows/ui-automated-tests.yml @@ -168,40 +168,24 @@ jobs: - name: Run Tests on to Create First Account ๐Ÿงช run: npm run mac.createAccountA - - name: Delete data from Friends Tests for artifact of Chat User A - working-directory: ./tests/fixtures/users/mac2/ - run: rm -rf ./FriendsTestUser/ - - - name: List all of the files extracted on Repo After First Account Created - run: | - pwd - ls -R - - - name: Upload test accounts for Chat User A - uses: actions/upload-artifact@v3 - if: always() - with: - name: account-first-user - path: ./tests/fixtures/users/mac2/ - - name: Run Tests on to Create Second Account ๐Ÿงช run: npm run mac.createAccountB - - name: Delete data from Friends Tests for artifact of Chat User B - working-directory: ./tests/fixtures/users/mac2/ - run: rm -rf ./FriendsTestUser/ - - name: List all of the files extracted on Repo After Second Account Created run: | pwd ls -R - - name: Upload test accounts for Chat User B + - name: Upload test accounts for Chat Users uses: actions/upload-artifact@v3 if: always() with: - name: account-second-user - path: ./tests/fixtures/users/mac2/ + name: appium-test-accounts + path: | + ./tests/fixtures/users/mac2/ChatUserA/ + ./tests/fixtures/users/mac2/ChatUserB/ + ./tests/fixtures/users/mac2/ChatUserA.json + ./tests/fixtures/users/mac2/ChatUserB.json - name: Add label if any of test jobs failed if: failure() @@ -234,18 +218,12 @@ jobs: name: Uplink-macos-latest path: ./apps - - name: Download Test User Account User A ๐Ÿ—ณ๏ธ + - name: Download Test User Accounts ๐Ÿ—ณ๏ธ uses: actions/download-artifact@v3 with: - name: account-first-user - path: ./tests/fixtures/users/mac2/ - - - name: Download Test User Account User A ๐Ÿ—ณ๏ธ - uses: actions/download-artifact@v3 - with: - name: account-second-user - path: ./tests/fixtures/users/mac2/ - + name: appium-test-accounts + path: ./tests/fixtures/users/mac2 + - name: List all of the files extracted run: | pwd @@ -378,5 +356,4 @@ jobs: test-allure-mac-ci test-allure-mac-chatA test-allure-mac-chatB - account-first-user - account-second-user + appium-test-accounts From ab3c5af57344bcdebab342b04cd8f8f7361fb4bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Carden=CC=83a?= <35935591+luisecm@users.noreply.github.com> Date: Wed, 1 Nov 2023 08:32:39 -0600 Subject: [PATCH 09/22] chore(appium): fixing copy directories --- .github/workflows/ui-automated-tests.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ui-automated-tests.yml b/.github/workflows/ui-automated-tests.yml index ed23da245f7..5cd91e7326b 100644 --- a/.github/workflows/ui-automated-tests.yml +++ b/.github/workflows/ui-automated-tests.yml @@ -174,7 +174,7 @@ jobs: - name: List all of the files extracted on Repo After Second Account Created run: | pwd - ls -R + ls -R -la - name: Upload test accounts for Chat Users uses: actions/upload-artifact@v3 @@ -227,7 +227,7 @@ jobs: - name: List all of the files extracted run: | pwd - ls -R + ls -R -la - name: Enable opening app not codesigned ๐Ÿ–ฅ๏ธ run: sudo spctl --master-disable @@ -276,13 +276,13 @@ jobs: name: Delete Cache Folder and copy reusable data for ${{ matrix.username }} run: | rm -rf ~/.uplink - cp -r ./tests/fixtures/users/${{ matrix.username }}/. ~/.uplink + cp -r ./tests/fixtures/users/mac2/${{ matrix.username }}/ ~/.uplink - name: Show if data was copied correctly working-directory: ~/.uplink run: | pwd - ls -R + ls -R -la - name: Run Tests on MacOS ๐Ÿงช run: npm run mac.${{ matrix.job }} From 9ed0634b807b3310468bc16754a98e5d33952fef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Carden=CC=83a?= <35935591+luisecm@users.noreply.github.com> Date: Wed, 1 Nov 2023 10:16:48 -0600 Subject: [PATCH 10/22] chore(appium): remove show files steps not required --- .github/workflows/ui-automated-tests.yml | 18 +----------------- config/macos-chats/wdio.mac.chatA.conf.ts | 10 ---------- config/macos-chats/wdio.mac.chatB.conf.ts | 9 --------- 3 files changed, 1 insertion(+), 36 deletions(-) diff --git a/.github/workflows/ui-automated-tests.yml b/.github/workflows/ui-automated-tests.yml index 5cd91e7326b..e4910619231 100644 --- a/.github/workflows/ui-automated-tests.yml +++ b/.github/workflows/ui-automated-tests.yml @@ -170,12 +170,7 @@ jobs: - name: Run Tests on to Create Second Account ๐Ÿงช run: npm run mac.createAccountB - - - name: List all of the files extracted on Repo After Second Account Created - run: | - pwd - ls -R -la - + - name: Upload test accounts for Chat Users uses: actions/upload-artifact@v3 if: always() @@ -224,11 +219,6 @@ jobs: name: appium-test-accounts path: ./tests/fixtures/users/mac2 - - name: List all of the files extracted - run: | - pwd - ls -R -la - - name: Enable opening app not codesigned ๐Ÿ–ฅ๏ธ run: sudo spctl --master-disable @@ -278,12 +268,6 @@ jobs: rm -rf ~/.uplink cp -r ./tests/fixtures/users/mac2/${{ matrix.username }}/ ~/.uplink - - name: Show if data was copied correctly - working-directory: ~/.uplink - run: | - pwd - ls -R -la - - name: Run Tests on MacOS ๐Ÿงช run: npm run mac.${{ matrix.job }} diff --git a/config/macos-chats/wdio.mac.chatA.conf.ts b/config/macos-chats/wdio.mac.chatA.conf.ts index 6e93a396800..e55d3349852 100644 --- a/config/macos-chats/wdio.mac.chatA.conf.ts +++ b/config/macos-chats/wdio.mac.chatA.conf.ts @@ -1,7 +1,6 @@ import "module-alias/register"; import allureReporter from '@wdio/allure-reporter' import { config as sharedConfig } from '@config/wdio.shared.conf'; -import { homedir } from "os"; import { join } from "path"; import { MACOS_BUNDLE_ID, MACOS_DRIVER } from "@helpers/constants"; const fsp = require("fs").promises; @@ -97,7 +96,6 @@ export const config: WebdriverIO.Config = { // methods to it. If one of them returns with a promise, WebdriverIO will wait until that promise got // resolved to continue. onPrepare: async function() { - const cacheFolder = homedir() + "/.uplink/.user"; const allureResultsFolder = join(process.cwd(), "./allure-results"); const testReportFolder = join(process.cwd(), "./test-report"); const testResultsFolder = join(process.cwd(), "./test-results"); @@ -111,14 +109,6 @@ export const config: WebdriverIO.Config = { `Got an error trying to delete artifacts folders: ${error.message}` ); } - try { - await rmSync(cacheFolder, { recursive: true, force: true }); - console.log("Deleted Cache Folder Successfully!"); - } catch (error) { - console.error( - `Got an error trying to delete Cache Folder: ${error.message}` - ); - } }, afterTest: async function (test, describe, { error }) { diff --git a/config/macos-chats/wdio.mac.chatB.conf.ts b/config/macos-chats/wdio.mac.chatB.conf.ts index a989ffc105b..2b83c739ab5 100644 --- a/config/macos-chats/wdio.mac.chatB.conf.ts +++ b/config/macos-chats/wdio.mac.chatB.conf.ts @@ -97,7 +97,6 @@ export const config: WebdriverIO.Config = { // methods to it. If one of them returns with a promise, WebdriverIO will wait until that promise got // resolved to continue. onPrepare: async function() { - const cacheFolder = homedir() + "/.uplink/.user"; const allureResultsFolder = join(process.cwd(), "./allure-results"); const testReportFolder = join(process.cwd(), "./test-report"); const testResultsFolder = join(process.cwd(), "./test-results"); @@ -111,14 +110,6 @@ export const config: WebdriverIO.Config = { `Got an error trying to delete artifacts folders: ${error.message}` ); } - try { - await rmSync(cacheFolder, { recursive: true, force: true }); - console.log("Deleted Cache Folder Successfully!"); - } catch (error) { - console.error( - `Got an error trying to delete Cache Folder: ${error.message}` - ); - } }, afterTest: async function (test, describe, { error }) { From ec114c3f9b46109b7717bb58720bef4d7cd4ef36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Carden=CC=83a?= <35935591+luisecm@users.noreply.github.com> Date: Wed, 1 Nov 2023 17:59:50 -0600 Subject: [PATCH 11/22] test(update): start adding tests to execute on two runners --- .../ChatUserA/01-create-account.spec.ts | 20 --- .../ChatUserA/01-main-chats-userA.spec.ts | 150 ++++++++++++++++++ .../ChatUserA/02-chat-replies-userA.spec.ts | 73 +++++++++ .../ChatUserB/01-create-account.spec.ts | 20 --- .../ChatUserB/01-main-chats-userB.spec.ts | 87 ++++++++++ .../ChatUserB/02-chat-replies-userB.spec.ts | 68 ++++++++ tests/suites/Chats/02-ChatsUserA.suite.ts | 6 +- tests/suites/Chats/03-ChatsUserB.suite.ts | 6 +- 8 files changed, 384 insertions(+), 46 deletions(-) delete mode 100644 tests/specs/reusable-accounts/ChatUserA/01-create-account.spec.ts create mode 100644 tests/specs/reusable-accounts/ChatUserA/01-main-chats-userA.spec.ts create mode 100644 tests/specs/reusable-accounts/ChatUserA/02-chat-replies-userA.spec.ts delete mode 100644 tests/specs/reusable-accounts/ChatUserB/01-create-account.spec.ts create mode 100644 tests/specs/reusable-accounts/ChatUserB/01-main-chats-userB.spec.ts create mode 100644 tests/specs/reusable-accounts/ChatUserB/02-chat-replies-userB.spec.ts diff --git a/tests/specs/reusable-accounts/ChatUserA/01-create-account.spec.ts b/tests/specs/reusable-accounts/ChatUserA/01-create-account.spec.ts deleted file mode 100644 index 57bc26fe228..00000000000 --- a/tests/specs/reusable-accounts/ChatUserA/01-create-account.spec.ts +++ /dev/null @@ -1,20 +0,0 @@ -import "module-alias/register"; -import { - loginWithTestUser, -} from "@helpers/commands"; -import { USER_A_INSTANCE } from "@helpers/constants"; -import FriendsScreen from "@screenobjects/friends/FriendsScreen"; -import WelcomeScreen from "@screenobjects/welcome-screen/WelcomeScreen"; -let friendsScreenFirstUser = new FriendsScreen(USER_A_INSTANCE); -let welcomeScreenFirstUser = new WelcomeScreen(USER_A_INSTANCE); - - -export default async function friendRequestUserATests() { - it("Chat User A - Login with account previously created", async () => { - // Login with account previously created - await loginWithTestUser(); - await welcomeScreenFirstUser.validateWelcomeScreenIsShown(); - await welcomeScreenFirstUser.goToFriends() - await friendsScreenFirstUser.validateFriendsScreenIsShown(); - }) -} diff --git a/tests/specs/reusable-accounts/ChatUserA/01-main-chats-userA.spec.ts b/tests/specs/reusable-accounts/ChatUserA/01-main-chats-userA.spec.ts new file mode 100644 index 00000000000..a4838eed851 --- /dev/null +++ b/tests/specs/reusable-accounts/ChatUserA/01-main-chats-userA.spec.ts @@ -0,0 +1,150 @@ +import "module-alias/register"; +import { loginWithTestUser } from "@helpers/commands"; +import { USER_A_INSTANCE } from "@helpers/constants"; +import ChatsLayout from "@screenobjects/chats/ChatsLayout"; +import EmojiSelector from "@screenobjects/chats/EmojiSelector"; +import FavoritesSidebar from "@screenobjects/chats/FavoritesSidebar"; +import FriendsScreen from "@screenobjects/friends/FriendsScreen"; +import InputBar from "@screenobjects/chats/InputBar"; +import Messages from "@screenobjects/chats/Messages"; +import MessageGroup from "@screenobjects/chats/MessageGroup"; +import Topbar from "@screenobjects/chats/Topbar"; +import WelcomeScreen from "@screenobjects/welcome-screen/WelcomeScreen"; +let chatsMessagesFirstUser = new Messages(USER_A_INSTANCE); +let chatsMessageGroupsFirstUser = new MessageGroup(USER_A_INSTANCE); +let chatsInputFirstUser = new InputBar(USER_A_INSTANCE); +let chatsLayoutFirstUser = new ChatsLayout(USER_A_INSTANCE); +let chatsTopbarFirstUser = new Topbar(USER_A_INSTANCE); +let emojiSelectorFirstUser = new EmojiSelector(USER_A_INSTANCE); +let favoritesSidebarFirstUser = new FavoritesSidebar(USER_A_INSTANCE); +let friendsScreenFirstUser = new FriendsScreen(USER_A_INSTANCE); +let welcomeScreenFirstUser = new WelcomeScreen(USER_A_INSTANCE); + +export default async function mainChatsTestsUserA() { + it("Chat User A - Login with account previously created", async () => { + // Login with account previously created + await loginWithTestUser(); + await welcomeScreenFirstUser.validateWelcomeScreenIsShown(); + await welcomeScreenFirstUser.goToFriends(); + await friendsScreenFirstUser.validateFriendsScreenIsShown(); + }); + + it("Chat User A - Accept friend request from User A and go to chat button", async () => { + // With User A - Go to pending requests list, wait for receiving the friend request and accept it + await friendsScreenFirstUser.hoverOnPendingListButton(); + await friendsScreenFirstUser.goToPendingFriendsList(); + await friendsScreenFirstUser.validateIncomingListIsShown(); + await friendsScreenFirstUser.waitUntilFriendRequestIsReceived(); + await friendsScreenFirstUser.acceptIncomingRequest("ChatUserB"); + + // Validate friend is now on all friends list + await friendsScreenFirstUser.goToAllFriendsList(); + await friendsScreenFirstUser.validateAllFriendsListIsShown(); + await friendsScreenFirstUser.validateAllFriendsListIsNotEmpty(); + + // Go to Chat with User B + await friendsScreenFirstUser.chatWithFriendButton.click(); + }); + + it("Chat User A - Chat screen displays Messages secured text displayed on top of conversation", async () => { + await chatsTopbarFirstUser.validateTopbarExists(); + + // Validate E2E message is displayed on top of chat + const encryptedMessagesText = + await chatsLayoutFirstUser.encryptedMessagesText; + await encryptedMessagesText.waitForExist(); + await expect(encryptedMessagesText).toHaveTextContaining( + "Messages are secured by end-to-end encryption and sent over a peer-to-peer network.", + ); + }); + + it("Input Bar - Chars Counter on Input Bar displays 0/1024 before typing a text", async () => { + // Validate Char counter is displayed on Input Bar and it displays 0/1024 + const inputCharCounter = await chatsInputFirstUser.inputCharCounterText; + const inputCharMaxText = await chatsInputFirstUser.inputCharMaxText; + await expect(inputCharCounter).toHaveTextContaining("0"); + await expect(inputCharMaxText).toHaveTextContaining("/1024"); + }); + + it("Input Bar - Chars Counter on Input Bar displays the number of chars of text entered", async () => { + // Validate Char counter increases after typing a text + const inputCharCounter = await chatsInputFirstUser.inputCharCounterText; + const inputCharMaxText = await chatsInputFirstUser.inputCharMaxText; + await chatsInputFirstUser.typeMessageOnInput("Testing..."); + await expect(inputCharCounter).toHaveTextContaining("10"); + await expect(inputCharMaxText).toHaveTextContaining("/1024"); + }); + + it("Input Bar - Add emoji to the message to be sent", async () => { + // Add emoji to the message to be sent + await chatsInputFirstUser.clickOnEmojiButton(); + await emojiSelectorFirstUser.clickOnEmoji("๐Ÿ˜€"); + + // Validate Char counter increases after adding an emoji to input bar + const inputCharCounter = await chatsInputFirstUser.inputCharCounterText; + const inputCharMaxText = await chatsInputFirstUser.inputCharMaxText; + await expect(inputCharCounter).toHaveTextContaining("11"); + await expect(inputCharMaxText).toHaveTextContaining("/1024"); + }); + + it("Input Bar - Click on send button will send the message to the other user", async () => { + // Send message to the other user + await chatsInputFirstUser.clickOnSendMessage(); + await chatsMessagesFirstUser.waitForMessageSentToExist("Testing...๐Ÿ˜€"); + + const textFromMessage = + await chatsMessagesFirstUser.getFirstMessageSentText(); + await expect(textFromMessage).toHaveTextContaining("Testing...๐Ÿ˜€"); + }); + + it("Input Bar - Chars Counter on Input Bar displays 0/1024 after sending a message", async () => { + // Validate Char counter is displayed on Input Bar and it displays 0/1024 + const inputCharCounter = await chatsInputFirstUser.inputCharCounterText; + const inputCharMaxText = await chatsInputFirstUser.inputCharMaxText; + await expect(inputCharCounter).toHaveTextContaining("0"); + await expect(inputCharMaxText).toHaveTextContaining("/1024"); + }); + + it("Chat User A - Validate Chat Message displays timestamp and user who sent it", async () => { + //Timestamp from last message sent should be displayed + const timeAgo = + await chatsMessageGroupsFirstUser.getLastMessageSentTimeAgo(); + await expect(timeAgo).toHaveTextContaining( + /- (?:\d{1,2}\s+(?:second|minute)s?\s+ago|now)$/, + ); + await expect(timeAgo).toHaveTextContaining("ChatUserA"); + }); + + it("Chat User A - Validate Chat Message sent contents", async () => { + //Any message you sent yourself should appear within a colored message bubble + const messageText = await chatsMessagesFirstUser.getFirstMessageSentText(); + await expect(messageText).toHaveTextContaining("Testing...๐Ÿ˜€"); + }); + + it("Chat User A - Validate Chat Message Group displays username picture", async () => { + //Your user image should be displayed next to the message + const userImage = + await chatsMessageGroupsFirstUser.getLastGroupWrapSentImage(); + await userImage.waitForExist(); + }); + + it("Chat User A - Topbar information", async () => { + // Validate user image, username is displayed on Chat Topbar + await chatsTopbarFirstUser.validateTopbarUserImage(); + await chatsTopbarFirstUser.validateTopbarUserName("ChatUserB"); + }); + + it("Chat User A - Add user with active chat to Favorites", async () => { + // Add user to favorites + await chatsTopbarFirstUser.addToFavorites(); + await favoritesSidebarFirstUser.validateFavoritesAreShown(); + + // Favorites Sidebar User bubble should be displayed with image + await favoritesSidebarFirstUser.validateFavoritesUserImage("ChatUserB"); + }); + + it("Chat User A - Remove user with active chat from Favorites", async () => { + // Remove user from favorites + await chatsTopbarFirstUser.removeFromFavorites(); + }); +} diff --git a/tests/specs/reusable-accounts/ChatUserA/02-chat-replies-userA.spec.ts b/tests/specs/reusable-accounts/ChatUserA/02-chat-replies-userA.spec.ts new file mode 100644 index 00000000000..4e26e85fee5 --- /dev/null +++ b/tests/specs/reusable-accounts/ChatUserA/02-chat-replies-userA.spec.ts @@ -0,0 +1,73 @@ +import "module-alias/register"; +import { USER_A_INSTANCE } from "@helpers/constants"; +import ContextMenu from "@screenobjects/chats/ContextMenu"; +import InputBar from "@screenobjects/chats/InputBar"; +import MessageGroup from "@screenobjects/chats/MessageGroup"; +import Messages from "@screenobjects/chats/Messages"; +import ReplyPrompt from "@screenobjects/chats/ReplyPrompt"; +let chatsContextMenuFirstUser = new ContextMenu(USER_A_INSTANCE); +let chatsInputFirstUser = new InputBar(USER_A_INSTANCE); +let chatsMessageGroupsFirstUser = new MessageGroup(USER_A_INSTANCE); +let chatsMessagesFirstUser = new Messages(USER_A_INSTANCE); +let chatsReplyPromptFirstUser = new ReplyPrompt(USER_A_INSTANCE); + +export default async function repliesTestsUserA() { + it("Chat User A - Validate reply message contents", async () => { + // Switch control to User A + await chatsMessagesFirstUser.switchToOtherUserWindow(); + + // With User A - Validate that reply message is received + await chatsMessagesFirstUser.chatMessageReply.waitForExist(); + + // Validate message replied appears smaller above your reply + const replyReceived = await chatsMessagesFirstUser.getLastReply(); + const replyReceivedText = await chatsMessagesFirstUser.getLastReplyText(); + await replyReceived.waitForExist(); + await expect(replyReceivedText).toHaveTextContaining("Testing...๐Ÿ˜€"); + + // Validate reply message sent appears as last message + const textFromMessage = + await chatsMessagesFirstUser.getLastMessageReceivedText(); + await expect(textFromMessage).toHaveTextContaining("Reply"); + }); + + it("Chat User A - Validate reply message group contains timestamp", async () => { + //Timestamp from last message sent should be displayed + const timeAgo = + await chatsMessageGroupsFirstUser.getLastMessageReceivedTimeAgo(); + await expect(timeAgo).toHaveTextContaining( + /- (?:\d{1,2}\s+(?:second|minute)s?\s+ago|now)$/, + ); + await expect(timeAgo).toHaveTextContaining("ChatUserB"); + }); + + it("Chat User A - Validate reply message group contains user image", async () => { + //Your user image should be displayed next to the message + const userImage = + await chatsMessageGroupsFirstUser.getLastGroupWrapReceivedImage(); + await userImage.waitForExist(); + }); + + it("Chat User A - Reply to yourself", async () => { + // Open Context Menu on Last Message Sent + await chatsMessagesFirstUser.openContextMenuOnLastSent(); + await chatsContextMenuFirstUser.validateContextMenuIsOpen(); + await chatsContextMenuFirstUser.selectContextOptionReply(); + + // Type a reply and sent it + await chatsReplyPromptFirstUser.replyPopUp.waitForExist(); + await chatsInputFirstUser.typeMessageOnInput("SelfReply"); + await chatsInputFirstUser.clickOnSendMessage(); + await chatsReplyPromptFirstUser.waitForReplyModalToNotExist(); + + // Validate reply to self message is displayed on Chat Conversation + const repliedMessage = await chatsMessagesFirstUser.getLastReply(); + const repliedMessageText = await chatsMessagesFirstUser.getLastReplyText(); + await repliedMessage.waitForExist(); + await expect(repliedMessageText).toHaveTextContaining("Testing...๐Ÿ˜€"); + + // Validate reply message sent appears as last message + const message = await chatsMessagesFirstUser.getLastMessageSentText(); + await expect(message).toHaveTextContaining("SelfReply"); + }); +} diff --git a/tests/specs/reusable-accounts/ChatUserB/01-create-account.spec.ts b/tests/specs/reusable-accounts/ChatUserB/01-create-account.spec.ts deleted file mode 100644 index 996da0c32fe..00000000000 --- a/tests/specs/reusable-accounts/ChatUserB/01-create-account.spec.ts +++ /dev/null @@ -1,20 +0,0 @@ -import "module-alias/register"; -import { - loginWithTestUser, -} from "@helpers/commands"; -import { USER_A_INSTANCE } from "@helpers/constants"; -import FriendsScreen from "@screenobjects/friends/FriendsScreen"; -import WelcomeScreen from "@screenobjects/welcome-screen/WelcomeScreen"; -let friendsScreenFirstUser = new FriendsScreen(USER_A_INSTANCE); -let welcomeScreenFirstUser = new WelcomeScreen(USER_A_INSTANCE); - - -export default async function friendRequestUserBTests() { - it("Chat User B - Login with account previously created", async () => { - // Login with account previously created - await loginWithTestUser(); - await welcomeScreenFirstUser.validateWelcomeScreenIsShown(); - await welcomeScreenFirstUser.goToFriends() - await friendsScreenFirstUser.validateFriendsScreenIsShown(); - }) -} diff --git a/tests/specs/reusable-accounts/ChatUserB/01-main-chats-userB.spec.ts b/tests/specs/reusable-accounts/ChatUserB/01-main-chats-userB.spec.ts new file mode 100644 index 00000000000..6643b0d187e --- /dev/null +++ b/tests/specs/reusable-accounts/ChatUserB/01-main-chats-userB.spec.ts @@ -0,0 +1,87 @@ +import "module-alias/register"; +import { getUserKey, loginWithTestUser } from "@helpers/commands"; +import { USER_A_INSTANCE } from "@helpers/constants"; +import FriendsScreen from "@screenobjects/friends/FriendsScreen"; +import Messages from "@screenobjects/chats/Messages"; +import MessageGroup from "@screenobjects/chats/MessageGroup"; +import Topbar from "@screenobjects/chats/Topbar"; +import WelcomeScreen from "@screenobjects/welcome-screen/WelcomeScreen"; +let chatsMessagesFirstUser = new Messages(USER_A_INSTANCE); +let chatsMessageGroupsFirstUser = new MessageGroup(USER_A_INSTANCE); +let chatsTopbarFirstUser = new Topbar(USER_A_INSTANCE); +let friendsScreenFirstUser = new FriendsScreen(USER_A_INSTANCE); +let welcomeScreenFirstUser = new WelcomeScreen(USER_A_INSTANCE); + +export default async function mainChatsTestsUserB() { + it("Chat User B - Login with account previously created", async () => { + // Login with account previously created + await loginWithTestUser(); + await welcomeScreenFirstUser.validateWelcomeScreenIsShown(); + await welcomeScreenFirstUser.goToFriends(); + await friendsScreenFirstUser.validateFriendsScreenIsShown(); + }); + + it("Chat User B - Send friend request to User A", async () => { + // Obtain did key from Chat User B + const friendDidKey = await getUserKey("ChatUserA", USER_A_INSTANCE); + await friendsScreenFirstUser.enterFriendDidKey(friendDidKey); + await friendsScreenFirstUser.clickOnAddSomeoneButton(); + + // Wait for toast notification to be closed + await friendsScreenFirstUser.waitUntilNotificationIsClosed(); + + // Validate friend request appears on pending list + await friendsScreenFirstUser.hoverOnPendingListButton(); + await friendsScreenFirstUser.goToPendingFriendsList(); + await friendsScreenFirstUser.validateOutgoingListIsShown(); + await friendsScreenFirstUser.validateOutgoingListIsNotEmpty(); + + await friendsScreenFirstUser.goToAllFriendsList(); + await friendsScreenFirstUser.validateAllFriendsListIsShown(); + }); + + it("Chat User B - Validate friend request was accepted", async () => { + // With User A - Go to pending requests list, wait for receiving the friend request and accept it + await friendsScreenFirstUser.waitUntilUserAcceptedFriendRequest(); + + // Validate friend is now on all friends list + await friendsScreenFirstUser.goToAllFriendsList(); + await friendsScreenFirstUser.validateAllFriendsListIsShown(); + await friendsScreenFirstUser.validateAllFriendsListIsNotEmpty(); + }); + + it("Chat User B - Wait until the other user is connected", async () => { + // Go to the current list of All friends and then open a Chat conversation with ChatUserA + await friendsScreenFirstUser.chatWithFriendButton.waitForExist(); + await friendsScreenFirstUser.hoverOnChatWithFriendButton("ChatUserA"); + await friendsScreenFirstUser.chatWithFriendButton.click(); + await chatsTopbarFirstUser.validateTopbarExists(); + }); + + it("Chat User B - Assert message received from Chat User A", async () => { + // Validate message received from Chat User A + await chatsMessagesFirstUser.waitForReceivingMessage("Testing...๐Ÿ˜€"); + + //Any message you sent yourself should appear within a colored message bubble + const textFromMessage = + await chatsMessagesFirstUser.getLastMessageReceivedText(); + await expect(textFromMessage).toHaveTextContaining("Testing...๐Ÿ˜€"); + }); + + it("Chat User B - Validate Chat Message Group from remote user displays username picture", async () => { + //Your user image should be displayed next to the message + const userImage = + await chatsMessageGroupsFirstUser.getLastGroupWrapReceivedImage(); + await userImage.waitForExist(); + }); + + it("Chat User B - Validate Chat Message received displays timestamp and user who sent it", async () => { + //Timestamp should be displayed when you send a message + const timeAgo = + await chatsMessageGroupsFirstUser.getLastMessageReceivedTimeAgo(); + await expect(timeAgo).toHaveTextContaining( + /- (?:\d{1,2}\s+(?:second|minute)s?\s+ago|now)$/, + ); + await expect(timeAgo).toHaveTextContaining("ChatUserA"); + }); +} diff --git a/tests/specs/reusable-accounts/ChatUserB/02-chat-replies-userB.spec.ts b/tests/specs/reusable-accounts/ChatUserB/02-chat-replies-userB.spec.ts new file mode 100644 index 00000000000..82f5cca0599 --- /dev/null +++ b/tests/specs/reusable-accounts/ChatUserB/02-chat-replies-userB.spec.ts @@ -0,0 +1,68 @@ +import "module-alias/register"; +import { USER_A_INSTANCE } from "@helpers/constants"; +import ContextMenu from "@screenobjects/chats/ContextMenu"; +import InputBar from "@screenobjects/chats/InputBar"; +import MessageGroup from "@screenobjects/chats/MessageGroup"; +import Messages from "@screenobjects/chats/Messages"; +import ReplyPrompt from "@screenobjects/chats/ReplyPrompt"; +let chatsContextMenuFirstUser = new ContextMenu(USER_A_INSTANCE); +let chatsInputFirstUser = new InputBar(USER_A_INSTANCE); +let chatsMessageGroupsFirstUser = new MessageGroup(USER_A_INSTANCE); +let chatsMessagesFirstUser = new Messages(USER_A_INSTANCE); +let chatsReplyPromptFirstUser = new ReplyPrompt(USER_A_INSTANCE); + +export default async function repliesTestsUserB() { + it("Chat User B - Reply popup - Validate contents and close it", async () => { + // Open Context Menu on Last Message Received and select Reply + await chatsMessagesFirstUser.openContextMenuOnLastReceived(); + await chatsContextMenuFirstUser.validateContextMenuIsOpen(); + await chatsContextMenuFirstUser.selectContextOptionReply(); + + // Validate contents of Reply Pop Up and close it + await chatsReplyPromptFirstUser.validateReplyPromptElementsShown( + "Testing...๐Ÿ˜€", + ); + await chatsReplyPromptFirstUser.closeReplyModal(); + await chatsReplyPromptFirstUser.waitForReplyModalToNotExist(); + }); + + it("Chat User B - Reply to a message", async () => { + // Open Context Menu on Last Message Received and select Reply + await chatsMessagesFirstUser.openContextMenuOnLastReceived(); + await chatsContextMenuFirstUser.validateContextMenuIsOpen(); + await chatsContextMenuFirstUser.selectContextOptionReply(); + + // Type a reply and sent it + await chatsReplyPromptFirstUser.replyPopUp.waitForExist(); + await chatsInputFirstUser.typeMessageOnInput("Reply"); + await chatsInputFirstUser.clickOnSendMessage(); + await chatsReplyPromptFirstUser.waitForReplyModalToNotExist(); + }); + + it("Chat User B - Validate reply message group reply and message replied", async () => { + // Validate message replied appears smaller above your reply + const replySent = await chatsMessagesFirstUser.getLastReply(); + const replySentText = await chatsMessagesFirstUser.getLastReplyText(); + await replySent.waitForExist(); + await expect(replySentText).toHaveTextContaining("Testing...๐Ÿ˜€"); + + // Validate reply message sent appears as last message + const message = await chatsMessagesFirstUser.getLastMessageSentText(); + await expect(message).toHaveTextContaining("Reply"); + }); + + it("Chat User B - Validate reply message group contains timestamp and user image", async () => { + //Timestamp from last message sent should be displayed + const timeAgo = + await chatsMessageGroupsFirstUser.getLastMessageSentTimeAgo(); + await expect(timeAgo).toHaveTextContaining( + /- (?:\d{1,2}\s+(?:second|minute)s?\s+ago|now)$/, + ); + await expect(timeAgo).toHaveTextContaining("ChatUserB"); + + //Your user image should be displayed next to the message + const userImage = + await chatsMessageGroupsFirstUser.getLastGroupWrapSentImage(); + await userImage.waitForExist(); + }); +} diff --git a/tests/suites/Chats/02-ChatsUserA.suite.ts b/tests/suites/Chats/02-ChatsUserA.suite.ts index c5c5f372a9e..b7b40e3b33f 100644 --- a/tests/suites/Chats/02-ChatsUserA.suite.ts +++ b/tests/suites/Chats/02-ChatsUserA.suite.ts @@ -1,6 +1,6 @@ import "module-alias/register"; -import friendRequestUserATests from "@specs/reusable-accounts/ChatUserA/01-create-account.spec"; +import mainChatsTestsUserA from "@specs/reusable-accounts/ChatUserA/01-main-chats-userA.spec"; describe("MacOS Chats Tests - User A", async () => { - describe("Friends and Chat Main Tests", friendRequestUserATests.bind(this)); -}) \ No newline at end of file + describe("Accept friend request and Chat", mainChatsTestsUserA.bind(this)); +}); diff --git a/tests/suites/Chats/03-ChatsUserB.suite.ts b/tests/suites/Chats/03-ChatsUserB.suite.ts index 10c4ba3dcfc..07372222375 100644 --- a/tests/suites/Chats/03-ChatsUserB.suite.ts +++ b/tests/suites/Chats/03-ChatsUserB.suite.ts @@ -1,6 +1,6 @@ import "module-alias/register"; -import friendRequestUserBTests from "@specs/reusable-accounts/ChatUserB/01-create-account.spec"; +import mainChatsTestsUserB from "@specs/reusable-accounts/ChatUserB/01-main-chats-userB.spec"; describe("MacOS Chats Tests - User B", async () => { - describe("Friends and Chat Main Tests", friendRequestUserBTests.bind(this)); -}) \ No newline at end of file + describe("Send friend request and Chat", mainChatsTestsUserB.bind(this)); +}); From 5b1ab56983248fd97490e6af3edbb6d63f4fee96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Carden=CC=83a?= <35935591+luisecm@users.noreply.github.com> Date: Fri, 3 Nov 2023 17:16:46 -0600 Subject: [PATCH 12/22] test(update): finishing dividing tests into two specs --- .../ChatUserA/02-chat-replies-userA.spec.ts | 3 - .../03-message-context-menu-userA.spec.ts | 71 ++++++ .../ChatUserA/04-message-input-userA.spec.ts | 131 +++++++++++ .../05-message-attachments-userA.spec.ts | 79 +++++++ .../ChatUserA/06-chat-topbar-userA.spec.ts | 123 ++++++++++ .../ChatUserA/07-quick-profile-userA.spec.ts | 147 ++++++++++++ .../ChatUserA/08-sidebar-chats-userA.spec.ts | 210 ++++++++++++++++++ .../ChatUserA/09-group-chats-userA.spec.ts | 155 +++++++++++++ .../10-group-chat-edit-userA.spec.ts | 140 ++++++++++++ .../11-group-chats-sidebar-userA.spec.ts | 119 ++++++++++ .../03-message-context-menu-userB.spec.ts | 74 ++++++ .../ChatUserB/04-message-input-userB.spec.ts | 68 ++++++ .../05-message-attachments-userB.spec.ts | 176 +++++++++++++++ .../ChatUserB/06-quick-profile-userB.spec.ts | 68 ++++++ .../ChatUserB/07-sidebar-chats-userB.spec.ts | 73 ++++++ .../ChatUserB/08-group-chats-userB.spec.ts | 46 ++++ .../09-group-chat-edit-userB.spec.ts | 48 ++++ .../10-group-chats-sidebar-userB.spec.ts | 57 +++++ tests/suites/Chats/02-ChatsUserA.suite.ts | 20 ++ tests/suites/Chats/03-ChatsUserB.suite.ts | 18 ++ 20 files changed, 1823 insertions(+), 3 deletions(-) create mode 100644 tests/specs/reusable-accounts/ChatUserA/03-message-context-menu-userA.spec.ts create mode 100644 tests/specs/reusable-accounts/ChatUserA/04-message-input-userA.spec.ts create mode 100644 tests/specs/reusable-accounts/ChatUserA/05-message-attachments-userA.spec.ts create mode 100644 tests/specs/reusable-accounts/ChatUserA/06-chat-topbar-userA.spec.ts create mode 100644 tests/specs/reusable-accounts/ChatUserA/07-quick-profile-userA.spec.ts create mode 100644 tests/specs/reusable-accounts/ChatUserA/08-sidebar-chats-userA.spec.ts create mode 100644 tests/specs/reusable-accounts/ChatUserA/09-group-chats-userA.spec.ts create mode 100644 tests/specs/reusable-accounts/ChatUserA/10-group-chat-edit-userA.spec.ts create mode 100644 tests/specs/reusable-accounts/ChatUserA/11-group-chats-sidebar-userA.spec.ts create mode 100644 tests/specs/reusable-accounts/ChatUserB/03-message-context-menu-userB.spec.ts create mode 100644 tests/specs/reusable-accounts/ChatUserB/04-message-input-userB.spec.ts create mode 100644 tests/specs/reusable-accounts/ChatUserB/05-message-attachments-userB.spec.ts create mode 100644 tests/specs/reusable-accounts/ChatUserB/06-quick-profile-userB.spec.ts create mode 100644 tests/specs/reusable-accounts/ChatUserB/07-sidebar-chats-userB.spec.ts create mode 100644 tests/specs/reusable-accounts/ChatUserB/08-group-chats-userB.spec.ts create mode 100644 tests/specs/reusable-accounts/ChatUserB/09-group-chat-edit-userB.spec.ts create mode 100644 tests/specs/reusable-accounts/ChatUserB/10-group-chats-sidebar-userB.spec.ts diff --git a/tests/specs/reusable-accounts/ChatUserA/02-chat-replies-userA.spec.ts b/tests/specs/reusable-accounts/ChatUserA/02-chat-replies-userA.spec.ts index 4e26e85fee5..850b739adbb 100644 --- a/tests/specs/reusable-accounts/ChatUserA/02-chat-replies-userA.spec.ts +++ b/tests/specs/reusable-accounts/ChatUserA/02-chat-replies-userA.spec.ts @@ -13,9 +13,6 @@ let chatsReplyPromptFirstUser = new ReplyPrompt(USER_A_INSTANCE); export default async function repliesTestsUserA() { it("Chat User A - Validate reply message contents", async () => { - // Switch control to User A - await chatsMessagesFirstUser.switchToOtherUserWindow(); - // With User A - Validate that reply message is received await chatsMessagesFirstUser.chatMessageReply.waitForExist(); diff --git a/tests/specs/reusable-accounts/ChatUserA/03-message-context-menu-userA.spec.ts b/tests/specs/reusable-accounts/ChatUserA/03-message-context-menu-userA.spec.ts new file mode 100644 index 00000000000..de8a9ca0dd8 --- /dev/null +++ b/tests/specs/reusable-accounts/ChatUserA/03-message-context-menu-userA.spec.ts @@ -0,0 +1,71 @@ +import "module-alias/register"; +import { USER_A_INSTANCE } from "@helpers/constants"; +import ContextMenu from "@screenobjects/chats/ContextMenu"; +import InputBar from "@screenobjects/chats/InputBar"; +import MessageGroup from "@screenobjects/chats/MessageGroup"; +import Messages from "@screenobjects/chats/Messages"; +let chatsContextMenuFirstUser = new ContextMenu(USER_A_INSTANCE); +let chatsInputFirstUser = new InputBar(USER_A_INSTANCE); +let chatsMessagesFirstUser = new Messages(USER_A_INSTANCE); +let chatsMessageGroupsFirstUser = new MessageGroup(USER_A_INSTANCE); + +export default async function messageContextMenuTestsUserA() { + it("Chat User A - Send two messages to Chat User B", async () => { + // Send a message to Chat User B + await chatsInputFirstUser.typeMessageOnInput("Two..."); + await chatsInputFirstUser.clickOnSendMessage(); + await chatsMessagesFirstUser.waitForMessageSentToExist("Two..."); + + // Send a message to Chat User B + await chatsInputFirstUser.typeMessageOnInput("Three..."); + await chatsInputFirstUser.clickOnSendMessage(); + await chatsMessagesFirstUser.waitForMessageSentToExist("Three..."); + }); + + it("Chat User A - Context Menu - Delete Message", async () => { + // Open context menu on last message sent and select option for deleting + await chatsMessagesFirstUser.openContextMenuOnLastSent(); + await chatsContextMenuFirstUser.validateContextMenuIsOpen(); + await chatsContextMenuFirstUser.selectContextOptionDelete(); + + // Validate that last message was deleted and therefore the last message displayed is "two..." + const textMessage = await chatsMessagesFirstUser.getLastMessageSentText(); + await expect(textMessage).toHaveTextContaining("Two..."); + }); + + it("Chat User A - React to sent message and multiple reactions in a message", async () => { + // React with ๐Ÿ˜‚ emoji + await chatsMessagesFirstUser.openContextMenuOnLastSent(); + await chatsContextMenuFirstUser.validateContextMenuIsOpen(); + await chatsContextMenuFirstUser.clickOnFirstReaction(); + await chatsMessageGroupsFirstUser.waitUntilEmojiReactionSelfExists("๐Ÿ˜‚"); + + // React with ๐Ÿ–– emoji + await chatsMessagesFirstUser.openContextMenuOnLastSent(); + await chatsContextMenuFirstUser.validateContextMenuIsOpen(); + await chatsContextMenuFirstUser.clickOnSecondReaction(); + await chatsMessageGroupsFirstUser.waitUntilEmojiReactionSelfExists("๐Ÿ––"); + + // Validate reactions are displayed correctly + const reactions = + await chatsMessageGroupsFirstUser.getLastMessageSentSelfReactions(); + await expect(reactions.includes("๐Ÿ–– 1")).toEqual(true); + await expect(reactions.includes("๐Ÿ˜‚ 1")).toEqual(true); + }); + + it("Chat User A - React to received message", async () => { + // Validate message received from Chat User A + await chatsMessagesFirstUser.waitForReceivingMessage("Reply"); + + // React with ๐Ÿ‘Ž emoji + await chatsMessagesFirstUser.openContextMenuOnLastReceived(); + await chatsContextMenuFirstUser.validateContextMenuIsOpen(); + await chatsContextMenuFirstUser.clickOnThirdReaction(); + await chatsMessageGroupsFirstUser.waitUntilEmojiReactionSelfExists("๐Ÿ‘Ž"); + + // Validate reaction is displayed correctly + const reaction = + await chatsMessageGroupsFirstUser.getLastMessageReceivedSelfReactions(); + await expect(reaction.includes("๐Ÿ‘Ž 1")).toEqual(true); + }); +} diff --git a/tests/specs/reusable-accounts/ChatUserA/04-message-input-userA.spec.ts b/tests/specs/reusable-accounts/ChatUserA/04-message-input-userA.spec.ts new file mode 100644 index 00000000000..4205dcd658d --- /dev/null +++ b/tests/specs/reusable-accounts/ChatUserA/04-message-input-userA.spec.ts @@ -0,0 +1,131 @@ +import "module-alias/register"; +import { USER_A_INSTANCE, USER_B_INSTANCE } from "@helpers/constants"; +import InputBar from "@screenobjects/chats/InputBar"; +import Messages from "@screenobjects/chats/Messages"; +let chatsInputFirstUser = new InputBar(USER_A_INSTANCE); +let chatsMessagesFirstUser = new Messages(USER_A_INSTANCE); + +export default async function messageInputTestsUserA() { + it("Chat User A - Message Input - User cannot send empty messages", async () => { + // Ensure that input bar is empty and click on send message button + await chatsInputFirstUser.clearInputBar(); + await chatsInputFirstUser.clickOnInputBar(); + await chatsInputFirstUser.clickOnSendMessage(); + + // Ensure that input bar is empty and press Enter Key + await chatsInputFirstUser.clearInputBar(); + await chatsInputFirstUser.clickOnInputBar(); + await chatsInputFirstUser.pressEnterKeyOnInputBar(); + + // Validate latest message sent displayed on Chat Conversation is still "Two..." + const textMessage = await chatsMessagesFirstUser.getLastMessageSentText(); + await expect(textMessage).toHaveTextContaining("Two..."); + }); + + // Skipping test failing on CI due to slowness on driver typing 1024 characters + xit("Chat User A - Message Input - User can type up to 1024 chars on input bar", async () => { + // Generate a random text with 1024 chars + const longText = await chatsInputFirstUser.generateRandomText(); + // Type long text with 1024 chars on input bar and attempt to add 4 more chars (efgh) + await chatsInputFirstUser.typeMessageOnInput(longText + "efgh"); + + // Ensure that latest chars were not added to input bar, since the max number of chars has been reached + // Input bar text should be equal to long text with 1024 chars + await expect(chatsInputFirstUser.inputText).toHaveText(longText); + + // Clear input bar to finish test + await chatsInputFirstUser.clearInputBar(); + }); + + it("Chat Input Text - Validate texts with ** markdown are sent in bolds", async () => { + // With Chat User A, send a message with ** markdown + await chatsInputFirstUser.clearInputBar(); + await chatsInputFirstUser.typeMessageOnInput("**Bolds1**"); + await chatsInputFirstUser.clickOnSendMessage(); + await chatsMessagesFirstUser.waitForMessageSentToExist("Bolds1"); + }); + + it("Chat Input Text - Validate texts with __ markdown are sent in bolds", async () => { + // With Chat User A, send a message with __ markdown + await chatsInputFirstUser.typeMessageOnInput("__Bolds2__"); + await chatsInputFirstUser.clickOnSendMessage(); + await chatsMessagesFirstUser.waitForMessageSentToExist("Bolds2"); + }); + + it("Chat Input Text - Validate users can send messages using the code language markdown", async () => { + // With Chat User A, send a code snippet with JavaScript language + await chatsInputFirstUser.typeCodeOnInputBar("JavaScript", "let a = 1;"); + await chatsInputFirstUser.clickOnSendMessage(); + + // With Chat User A, validate code message was sent and is displayed correctly + await chatsMessagesFirstUser.waitForCodeMessageSentToExist("JavaScript"); + const codeMessageTextSent = + await chatsMessagesFirstUser.getLastMessageSentCodeMessage(); + await expect(codeMessageTextSent).toEqual("let a = 1;"); + }); + + // Skipping test that is failing often on CI - Requires investigation to improve execution + xit("Chat Input Text - Code Markdown - User can copy the message from the code block", async () => { + // With Chat User A, click on the copy button from code block of last chat message sent + await chatsMessagesFirstUser.clickOnCopyCodeOfLastMessageSent(); + + // Then, paste it into the input bar and assert the text contents on input bar + await chatsInputFirstUser.pasteClipboardOnInputBar(); + await expect(chatsInputFirstUser.inputText).toHaveText("let a = 1;"); + + // Finally, clear the input bar for next tests + await chatsInputFirstUser.clearInputBar(); + }); + + it("Chat Input Text - Validate text starting with https:// is sent as link", async () => { + // With Chat User A + await chatsInputFirstUser.typeMessageOnInput("https://www.google.com"); + await chatsInputFirstUser.clickOnSendMessage(); + await chatsMessagesFirstUser.waitForLinkSentToExist( + "https://www.google.com", + ); + }); + + it("Chat Input Text - Validate text starting with www. is sent as link", async () => { + // With Chat User A + await chatsInputFirstUser.typeMessageOnInput("www.apple.com"); + await chatsInputFirstUser.clickOnSendMessage(); + await chatsMessagesFirstUser.waitForLinkSentToExist("www.apple.com"); + }); + + it("Chat Input Text - Validate text starting with http:// is sent as link", async () => { + // With Chat User A + await chatsInputFirstUser.typeMessageOnInput("http://www.satellite.im"); + await chatsInputFirstUser.clickOnSendMessage(); + await chatsMessagesFirstUser.waitForLinkSentToExist( + "http://www.satellite.im", + ); + }); + + it("Chat User - Chat Messages containing links contents on local side", async () => { + // Validate link embed contents on chat message + const linkEmbedSent = + await chatsMessagesFirstUser.getLastMessageSentLinkEmbed(); + const linkEmbedSentDetailsText = + await chatsMessagesFirstUser.getLastMessageSentLinkEmbedDetailsText(); + const linkEmbedSentIcon = + await chatsMessagesFirstUser.getLastMessageSentLinkEmbedIcon(); + const linkEmbedSentIconTitle = + await chatsMessagesFirstUser.getLastMessageSentLinkEmbedIconTitle(); + + await linkEmbedSent.waitForExist(); + await expect(linkEmbedSentDetailsText).toHaveTextContaining( + "P2P Chat, Voice & Video Open-source, stored on IPFS. End to end encryption... trackers not included.", + ); + await linkEmbedSentIcon.waitForExist(); + await linkEmbedSentIconTitle.waitForExist(); + }); + + // Skipping test failing on because the typing indicator is gone before the test can validate it + xit("Typing Indicator - Send a long message to trigger typing indicator on remote side", async () => { + // Generate a random text with 100 chars + const shortText = await chatsInputFirstUser.generateShortRandomText(); + // Type the text with 90 chars on input bar + await chatsInputFirstUser.typeMessageOnInput(shortText + "efgh"); + }); +} diff --git a/tests/specs/reusable-accounts/ChatUserA/05-message-attachments-userA.spec.ts b/tests/specs/reusable-accounts/ChatUserA/05-message-attachments-userA.spec.ts new file mode 100644 index 00000000000..9940788b24b --- /dev/null +++ b/tests/specs/reusable-accounts/ChatUserA/05-message-attachments-userA.spec.ts @@ -0,0 +1,79 @@ +import "module-alias/register"; +import { USER_A_INSTANCE } from "@helpers/constants"; +import ComposeAttachment from "@screenobjects/chats/ComposeAttachment"; +import InputBar from "@screenobjects/chats/InputBar"; +import Messages from "@screenobjects/chats/Messages"; +let chatsAttachmentFirstUser = new ComposeAttachment(USER_A_INSTANCE); +let chatsInputFirstUser = new InputBar(USER_A_INSTANCE); +let chatsMessagesFirstUser = new Messages(USER_A_INSTANCE); + +export default async function messageAttachmentsTestsUserA() { + it("Send files from Browse Files - Message sent with attachments is shown on remote side", async () => { + // Ensure that message sent with attached file is displayed on remote side + // With User A- Validate that message with attachment was received + await chatsInputFirstUser.clickOnInputBar(); + await chatsMessagesFirstUser.chatMessageFileEmbedRemote.waitForExist(); + + // Validate text from message containing attachment + const message = await chatsMessagesFirstUser.getLastMessageReceivedText(); + await expect(message).toHaveTextContaining("Attached"); + }); + + it("Send Files on Chats - Validate compose attachments contents", async () => { + // Continue with test execution and clear input bar + await chatsInputFirstUser.clearInputBar(); + + // Click on upload button and attach a file to compose attachment + await chatsInputFirstUser.uploadFileFromLocalDisk( + "./tests/fixtures/testfile.txt", + ); + + // Validate contents on Compose Attachments are displayed + await chatsAttachmentFirstUser.composeAttachmentsFileEmbed.waitForExist(); + await chatsAttachmentFirstUser.composeAttachmentsFileIcon.waitForExist(); + await chatsAttachmentFirstUser.composeAttachmentsFileNameText.waitForExist(); + }); + + it("Send Files on Chats - Delete attachment before sending the message", async () => { + // Click on upload button and attach a file to compose attachment + await chatsAttachmentFirstUser.deleteFileOnComposeAttachment(); + }); + + it("Receive Files on Chats - Received Message with Attachment - Text Message contents", async () => { + // With User B - Validate that message with attachment was received + await chatsInputFirstUser.clickOnInputBar(); + await chatsMessagesFirstUser.chatMessageFileEmbedRemote.waitForExist(); + + // Validate text from message containing attachment + const message = await chatsMessagesFirstUser.getLastMessageReceivedText(); + await expect(message).toHaveTextContaining("Attached2"); + }); + + it("Receive Files on Chats - Attachment File Contents", async () => { + // Validate file metadata is displayed correctly on last chat message sent + const fileMeta = + await chatsMessagesFirstUser.getLastMessageReceivedFileMeta(); + await expect(fileMeta).toHaveTextContaining("47 B"); + + // Validate filename is displayed correctly on last chat message sent + const fileName = + await chatsMessagesFirstUser.getLastMessageReceivedFileName(); + await expect(fileName).toHaveTextContaining("testfile.txt"); + + // Validate file icon is displayed correctly on last chat message sent + const fileIcon = + await chatsMessagesFirstUser.getLastMessageReceivedFileIcon(); + await fileIcon.waitForExist(); + + // Validate file download button is displayed correctly on last chat message sent + await chatsMessagesFirstUser.hoverOnLastFileReceived(); + const fileDownloadButton = + await chatsMessagesFirstUser.getLastMessageReceivedDownloadButton(); + await fileDownloadButton.waitForExist(); + }); + + it("Chat Messages with Files - Remote user can download file received", async () => { + // Download latest image file received + await chatsMessagesFirstUser.downloadLastReceivedFile(".txt"); + }); +} diff --git a/tests/specs/reusable-accounts/ChatUserA/06-chat-topbar-userA.spec.ts b/tests/specs/reusable-accounts/ChatUserA/06-chat-topbar-userA.spec.ts new file mode 100644 index 00000000000..94bdd65a223 --- /dev/null +++ b/tests/specs/reusable-accounts/ChatUserA/06-chat-topbar-userA.spec.ts @@ -0,0 +1,123 @@ +import "module-alias/register"; +import InputBar from "@screenobjects/chats/InputBar"; +import ContextMenu from "@screenobjects/chats/ContextMenu"; +import Messages from "@screenobjects/chats/Messages"; +import MessageGroup from "@screenobjects/chats/MessageGroup"; +import PinnedMessages from "@screenobjects/chats/PinnedMessages"; +import Topbar from "@screenobjects/chats/Topbar"; +import { USER_A_INSTANCE } from "@helpers/constants"; +let chatsContextMenuFirstUser = new ContextMenu(USER_A_INSTANCE); +let chatsInputFirstUser = new InputBar(USER_A_INSTANCE); +let chatsMessagesFirstUser = new Messages(USER_A_INSTANCE); +let chatsMessageGroupsFirstUser = new MessageGroup(USER_A_INSTANCE); +let chatsTopbarFirstUser = new Topbar(USER_A_INSTANCE); +let pinnedMessagesFirstUser = new PinnedMessages(USER_A_INSTANCE); + +export default async function chatTopbarTestsUserA() { + it("Chat User A - Validate Chat Screen tooltips are displayed", async () => { + // Validate Favorites button tooltip + await chatsTopbarFirstUser.hoverOnFavoritesButton(); + const favoritesAddTooltipText = + await chatsTopbarFirstUser.topbarAddToFavoritesTooltipText; + await expect(favoritesAddTooltipText).toHaveTextContaining( + "Add to Favorites", + ); + + // Validate Pinned Messages button tooltip + await chatsTopbarFirstUser.hoverOnPinnedMessagesButton(); + const pinnedMessagesTooltipText = + await chatsTopbarFirstUser.topbarPinnedMessagesTooltipText; + await expect(pinnedMessagesTooltipText).toHaveTextContaining( + "Pinned Messages", + ); + + // Validate Upload button tooltip + await chatsInputFirstUser.hoverOnUploadButton(); + const uploadTooltipText = await chatsInputFirstUser.uploadTooltipText; + await expect(uploadTooltipText).toHaveTextContaining("Upload"); + + // Validate Send button tooltip + await chatsInputFirstUser.hoverOnSendButton(); + const sendMessageTooltipText = + await chatsInputFirstUser.sendMessageTooltipText; + await expect(sendMessageTooltipText).toHaveTextContaining("Send"); + }); + + it("Chat User A - Validate Chat Screen tooltips for Call and Videocall display Coming soon", async () => { + // Validate Call button tooltip contains "Coming soon" + await chatsTopbarFirstUser.hoverOnCallButton(); + const callTooltipText = await chatsTopbarFirstUser.topbarCallTooltipText; + await expect(callTooltipText).toHaveTextContaining("Coming soon"); + + // Validate Videocall button tooltip contains "Coming soon" + await chatsTopbarFirstUser.hoverOnVideocallButton(); + const videoCallTooltipText = + await chatsTopbarFirstUser.topbarVideocallTooltipText; + await expect(videoCallTooltipText).toHaveTextContaining("Coming soon"); + }); + + it("Pinned Messages - Container is empty when no pinned messages have been added", async () => { + // Go to Pinned Messages and validate container is empty + await chatsTopbarFirstUser.clickOnPinnedMessages(); + await pinnedMessagesFirstUser.validatePinnedMessagesIsDisplayed(); + await pinnedMessagesFirstUser.validateEmptyPinnedMessagesIsDisplayed(); + + // Exit from Pinned Messages + await chatsTopbarFirstUser.clickOnPinnedMessages(); + }); + + it("Pinned Messages - Pin a message with attachments", async () => { + // Look for the latest message received by User A, open context menu and pin message + await chatsMessagesFirstUser.openContextMenuOnLastReceived(); + await chatsContextMenuFirstUser.validateContextMenuIsOpen(); + await chatsContextMenuFirstUser.selectContextOptionPin(); + + // Ensure that message shows a pin indicator + await chatsMessageGroupsFirstUser.validateLastMessageReceivedHasPinIndicator(); + }); + + it("Pinned Messages - Pinned message shows timestamp, sender and message", async () => { + // Go to Pinned Messages and validate container shows message + await chatsTopbarFirstUser.clickOnPinnedMessages(); + await pinnedMessagesFirstUser.validatePinnedMessagesIsDisplayed(); + + // Validate pinned message shows timestamp, sender and message + await pinnedMessagesFirstUser.validateFirstPinnedMessageImageProfileIsShown(); + await pinnedMessagesFirstUser.validateFirstPinnedMessageTimestampIsShown(); + await pinnedMessagesFirstUser.validateFirstPinnedMessageSender("ChatUserB"); + await pinnedMessagesFirstUser.validateFirstPinnedMessageText("Attached2"); + }); + + it("Pinned Messages - Pinned message with attachment shows icon, extension, filename and metadata", async () => { + // Validate attachment elements are shown in pinned message + await pinnedMessagesFirstUser.validateFirstPinnedMessageAttachmentFileIcon(); + await pinnedMessagesFirstUser.validateFirstPinnedMessageAttachmentFileIconExtension( + "txt", + ); + await pinnedMessagesFirstUser.validateFirstPinnedMessageAttachmentFileMeta( + "47 B", + ); + await pinnedMessagesFirstUser.validateFirstPinnedMessageAttachmentFileName( + "testfile.txt", + ); + }); + + it("Pinned Messages - User can be redirected to the message when clicking on Go to message", async () => { + // Click on Go to Message + await pinnedMessagesFirstUser.clickOnGoToMessage(0); + + // Open pinned messages + await chatsTopbarFirstUser.clickOnPinnedMessages(); + }); + + it("Pinned Messages - Remove a pinned message", async () => { + // Click on Unpin button to remove message from pinned messages + await pinnedMessagesFirstUser.clickOnUnpinMessage(0); + + // Validate that no posts are pinned + await pinnedMessagesFirstUser.validateEmptyPinnedMessagesIsDisplayed(); + + // Close pinned messages + await chatsTopbarFirstUser.clickOnPinnedMessages(); + }); +} diff --git a/tests/specs/reusable-accounts/ChatUserA/07-quick-profile-userA.spec.ts b/tests/specs/reusable-accounts/ChatUserA/07-quick-profile-userA.spec.ts new file mode 100644 index 00000000000..7945249d73b --- /dev/null +++ b/tests/specs/reusable-accounts/ChatUserA/07-quick-profile-userA.spec.ts @@ -0,0 +1,147 @@ +import "module-alias/register"; +import { getUserKey } from "@helpers/commands"; +import { USER_A_INSTANCE } from "@helpers/constants"; +import FriendsScreen from "@screenobjects/friends/FriendsScreen"; +import InputBar from "@screenobjects/chats/InputBar"; +import MessageGroup from "@screenobjects/chats/MessageGroup"; +import Messages from "@screenobjects/chats/Messages"; +import QuickProfile from "@screenobjects/chats/QuickProfile"; +import Topbar from "@screenobjects/chats/Topbar"; +import SettingsProfileScreen from "@screenobjects/settings/SettingsProfileScreen"; +import WelcomeScreen from "@screenobjects/welcome-screen/WelcomeScreen"; + +let chatsInputFirstUser = new InputBar(USER_A_INSTANCE); +let chatsMessageGroupsFirstUser = new MessageGroup(USER_A_INSTANCE); +let chatsMessagesFirstUser = new Messages(USER_A_INSTANCE); +let chatsQuickProfileFirstUser = new QuickProfile(USER_A_INSTANCE); +let chatsTopbarFirstUser = new Topbar(USER_A_INSTANCE); +let friendsScreenFirstUser = new FriendsScreen(USER_A_INSTANCE); +let settingsProfileFirstUser = new SettingsProfileScreen(USER_A_INSTANCE); +let welcomeScreenFirstUser = new WelcomeScreen(USER_A_INSTANCE); + +export default async function quickProfileTestsUserA() { + it("Chat User A - Validate contents from local quick profile", async () => { + // Open quick profile from remote user + await chatsMessageGroupsFirstUser.openLocalQuickProfile(); + await chatsQuickProfileFirstUser.quickProfile.waitForExist(); + + // Validate contents from quick profile + await chatsQuickProfileFirstUser.quickProfileUserImage.waitForExist(); + await chatsQuickProfileFirstUser.quickProfileBannerImage.waitForExist(); + await chatsQuickProfileFirstUser.quickProfileEditProfile.waitForExist(); + const quickProfileUsername = + await chatsQuickProfileFirstUser.quickProfileUserNameValueText; + await expect(quickProfileUsername).toHaveTextContaining("ChatUserA"); + }); + + it("Chat User A - Click on Edit Profile", async () => { + // Click on Edit Profile from Quick Profile + await chatsQuickProfileFirstUser.clickOnEditProfile(); + await settingsProfileFirstUser.validateSettingsProfileIsShown(); + await settingsProfileFirstUser.goToMainScreen(); + }); + + it("Chat User A - Validate contents from remote quick profile", async () => { + // With User A - Validate that message was received + await chatsInputFirstUser.clickOnInputBar(); + await chatsMessagesFirstUser.waitForReceivingMessage("click..."); + + // Open quick profile from remote user + await chatsMessageGroupsFirstUser.openRemoteQuickProfile(); + + // Validate quick profile is displayed + await chatsQuickProfileFirstUser.quickProfile.waitForExist(); + + // Validate contents from quick profile + await chatsQuickProfileFirstUser.quickProfileUserImage.waitForExist(); + await chatsQuickProfileFirstUser.quickProfileBannerImage.waitForExist(); + await chatsQuickProfileFirstUser.quickProfileRemoveFriend.waitForExist(); + await chatsQuickProfileFirstUser.quickProfileBlockUser.waitForExist(); + + // Validate username from quick profile + const quickProfileUsername = + await chatsQuickProfileFirstUser.quickProfileUserNameValueText; + await expect(quickProfileUsername).toHaveTextContaining("ChatUserB"); + + // Click outside to close quick profile + await chatsInputFirstUser.clickOnInputBar(); + }); + + it("Chat User A - Remove Friend", async () => { + // Open quick profile from remote user + await chatsMessageGroupsFirstUser.openRemoteQuickProfile(); + await chatsQuickProfileFirstUser.quickProfile.waitForExist(); + + // Click on Remove Friend from Quick Profile + await chatsQuickProfileFirstUser.clickOnRemoveUser(); + + // Welcome Screen should be displayed + await welcomeScreenFirstUser.skeletalUser.waitForExist(); + }); + + it("Chat User A - Ensure that Chat User B is not in friends list now", async () => { + // Get current list of All friends and ensure that it does not include the removed user + await welcomeScreenFirstUser.goToFriends(); + const allFriendsList = await friendsScreenFirstUser.getAllFriendsList(); + const includesFriend = await allFriendsList.includes("ChatUserB"); + await expect(includesFriend).toEqual(false); + }); + + it("Chat User A - Send friend request again to User B", async () => { + // Obtain did key from Chat User B + const friendDidKey = await getUserKey("ChatUserB", USER_A_INSTANCE); + await friendsScreenFirstUser.enterFriendDidKey(friendDidKey); + await friendsScreenFirstUser.clickOnAddSomeoneButton(); + + // Wait for toast notification to be closed + await friendsScreenFirstUser.waitUntilNotificationIsClosed(); + + // Validate friend request appears on pending list + await friendsScreenFirstUser.hoverOnPendingListButton(); + await friendsScreenFirstUser.goToPendingFriendsList(); + await friendsScreenFirstUser.validateOutgoingListIsShown(); + await friendsScreenFirstUser.validateOutgoingListIsNotEmpty(); + }); + + it("Chat User A - Wait until friend request is accepted again", async () => { + // Validate friend is now on all friends list + await friendsScreenFirstUser.goToAllFriendsList(); + await friendsScreenFirstUser.validateAllFriendsListIsShown(); + await friendsScreenFirstUser.validateAllFriendsListIsNotEmpty(); + + // Go to chat with User B + await friendsScreenFirstUser.validateChatWithFriendButtonIsShown(); + await friendsScreenFirstUser.hoverOnChatWithFriendButton("ChatUserB"); + await friendsScreenFirstUser.clickOnChatWithFriend(); + + // Validate that Topbar is displayed + await chatsTopbarFirstUser.validateTopbarExists(); + }); + + it("Chat User A - Block Friend", async () => { + // With User A - Validate that message was received + await chatsMessagesFirstUser.waitForReceivingMessage("Accepted..."); + + // Open quick profile from remote user + await chatsMessageGroupsFirstUser.openRemoteQuickProfile(); + await chatsQuickProfileFirstUser.quickProfile.waitForExist(); + + // Click on Block Friend from Quick Profile + await chatsQuickProfileFirstUser.clickOnBlockUser(); + + // Welcome Screen should be displayed + await welcomeScreenFirstUser.validateWelcomeScreenIsShown(); + }); + + it("Chat User A - Ensure that Chat User B is in blocked list now", async () => { + // Get current list of Blocked friends and ensure that it includes the blocked user + await welcomeScreenFirstUser.goToFriends(); + await friendsScreenFirstUser.goToBlockedList(); + await friendsScreenFirstUser.validateBlockedListIsShown(); + await friendsScreenFirstUser.validateBlockedListIsNotEmpty(); + + // Validate that blocked user is on blocked list + await friendsScreenFirstUser.goToAllFriendsList(); + await friendsScreenFirstUser.validateAllFriendsListIsShown(); + }); +} diff --git a/tests/specs/reusable-accounts/ChatUserA/08-sidebar-chats-userA.spec.ts b/tests/specs/reusable-accounts/ChatUserA/08-sidebar-chats-userA.spec.ts new file mode 100644 index 00000000000..c0fc5c2561a --- /dev/null +++ b/tests/specs/reusable-accounts/ChatUserA/08-sidebar-chats-userA.spec.ts @@ -0,0 +1,210 @@ +import "module-alias/register"; +import { getUserKey } from "@helpers/commands"; +import { USER_A_INSTANCE } from "@helpers/constants"; +import ChatsLayout from "@screenobjects/chats/ChatsLayout"; +import ChatsSidebar from "@screenobjects/chats/ChatsSidebar"; +import ContextMenuSidebar from "@screenobjects/chats/ContextMenuSidebar"; +import FavoritesSidebar from "@screenobjects/chats/FavoritesSidebar"; +import InputBar from "@screenobjects/chats/InputBar"; +import Messages from "@screenobjects/chats/Messages"; +import Topbar from "@screenobjects/chats/Topbar"; +import FilesScreen from "@screenobjects/files/FilesScreen"; +import FriendsScreen from "@screenobjects/friends/FriendsScreen"; +import SettingsProfileScreen from "@screenobjects/settings/SettingsProfileScreen"; +import WelcomeScreen from "@screenobjects/welcome-screen/WelcomeScreen"; +let chatsInputFirstUser = new InputBar(USER_A_INSTANCE); +let chatsLayoutFirstUser = new ChatsLayout(USER_A_INSTANCE); +let chatsMessagesFirstUser = new Messages(USER_A_INSTANCE); +let chatsSidebarFirstUser = new ChatsSidebar(USER_A_INSTANCE); +let chatsTopbarFirstUser = new Topbar(USER_A_INSTANCE); +let contextMenuSidebarFirstUser = new ContextMenuSidebar(USER_A_INSTANCE); +let favoritesSidebarFirstUser = new FavoritesSidebar(USER_A_INSTANCE); +let filesScreenFirstUser = new FilesScreen(USER_A_INSTANCE); +let friendsScreenFirstUser = new FriendsScreen(USER_A_INSTANCE); +let settingsProfileFirstUser = new SettingsProfileScreen(USER_A_INSTANCE); +let welcomeScreenFirstUser = new WelcomeScreen(USER_A_INSTANCE); + +export default async function sidebarChatsTestsUserA() { + it("Chat User A - Unblock the other Chat User", async () => { + // Unblock Chat User B and go to Friends List to send a new friend request + await friendsScreenFirstUser.validateFriendsScreenIsShown(); + await friendsScreenFirstUser.hoverOnBlockedListButton(); + await friendsScreenFirstUser.goToBlockedList(); + await friendsScreenFirstUser.validateBlockedListIsShown(); + await friendsScreenFirstUser.validateBlockedListIsNotEmpty(); + await friendsScreenFirstUser.removeOrCancelUser("ChatUserB"); + await friendsScreenFirstUser.removeOrDenyFriendButton.waitForExist({ + reverse: true, + }); + await friendsScreenFirstUser.goToAllFriendsList(); + await friendsScreenFirstUser.validateAllFriendsListIsShown(); + }); + + it("Chat User A - Send friend request again to Chat User B", async () => { + // Obtain did key from Chat User B + const friendDidKey = await getUserKey("ChatUserB", USER_A_INSTANCE); + await friendsScreenFirstUser.enterFriendDidKey(friendDidKey); + await friendsScreenFirstUser.clickOnAddSomeoneButton(); + + // Wait for toast notification to be closed + await friendsScreenFirstUser.waitUntilNotificationIsClosed(); + + // Validate that friend request was sent + await friendsScreenFirstUser.hoverOnPendingListButton(); + await friendsScreenFirstUser.goToPendingFriendsList(); + await friendsScreenFirstUser.validateOutgoingListIsShown(); + await friendsScreenFirstUser.validateRemoveOrDenyButtonIsShown(); + }); + + it("Chat User A - Wait until Chat User B accepts friend request and sends a message", async () => { + // Validate last message contents on Sidebar displays hello on bolds and not __hello__ + await chatsSidebarFirstUser.validateLastMessageDisplayed("hello"); + + // With User A - Wait until user B accepts the friend request + await friendsScreenFirstUser.goToAllFriendsList(); + await friendsScreenFirstUser.validateAllFriendsListIsShown(); + await friendsScreenFirstUser.validateAllFriendsListIsShown(); + await friendsScreenFirstUser.waitUntilUserAcceptedFriendRequest(); + + // Go to another part of the app + await friendsScreenFirstUser.goToMainScreen(); + + // Wait until message is received + await chatsSidebarFirstUser.waitForReceivingMessageOnSidebar(); + }); + + it("Chat User A - Sidebar - Any active chats user has created should appear in Sidebar", async () => { + // Validate Sidebar shows Username + await chatsSidebarFirstUser.validateUsernameDisplayed("ChatUserB"); + + // Validate number of unread messages is displayed on sidebar + await chatsSidebarFirstUser.validateNumberOfUnreadMessages("1"); + + // Validate time ago displayed on sidebar + await chatsSidebarFirstUser.validateLastMessageTimeAgo(); + }); + + it("Sidebar - Message preview on Sidebar should display the message without the markdown characters", async () => { + // Validate last message contents on Sidebar displays hello on bolds and not __hello__ + await chatsSidebarFirstUser.validateLastMessageDisplayed("hello"); + }); + + it("Chat User A - Sidebar - Context Menu - Clear Unreads", async () => { + // Open context menu and right click on Clear Unreads + await chatsSidebarFirstUser.openContextMenuOnSidebar("ChatUserB"); + await contextMenuSidebarFirstUser.selectChatsClearUnreads(); + await chatsSidebarFirstUser.validateNoUnreadMessages(); + }); + + it("Chat User A - Sidebar - Context Menu - Hide chat", async () => { + // Open context menu and right click on Hide chat + await chatsSidebarFirstUser.openContextMenuOnSidebar("ChatUserB"); + await contextMenuSidebarFirstUser.selectChatsHideChat(); + await chatsSidebarFirstUser.validateSidebarChatIsNotDisplayed("ChatUserB"); + }); + + it("Chat User A - Sidebar - Send a message to User B", async () => { + // Go to the current list of All friends and then open a Chat conversation with ChatUserA + await welcomeScreenFirstUser.goToFriends(); + await friendsScreenFirstUser.validateChatWithFriendButtonIsShown(); + await friendsScreenFirstUser.hoverOnChatWithFriendButton("ChatUserB"); + await friendsScreenFirstUser.clickOnChatWithFriend(); + await chatsLayoutFirstUser.validateChatLayoutIsShown(); + + // Send message to Chat User B + await chatsInputFirstUser.typeMessageOnInput("Hi..."); + await chatsInputFirstUser.clickOnSendMessage(); + await chatsMessagesFirstUser.waitForMessageSentToExist("Hi..."); + }); + + it("Chat User A - Sidebar - Persists between different sections of the app - Files Screen", async () => { + // Validate on Files Screen that sidebar is displayed + await chatsLayoutFirstUser.goToFiles(); + await filesScreenFirstUser.validateFilesScreenIsShown(); + await chatsSidebarFirstUser.validateSidebarChatsIsShown(); + }); + + it("Chat User A - Chats Sidebar is hidden when entering to Settings Screen", async () => { + // Go to Settings Profile Screen + await filesScreenFirstUser.goToSettings(); + await settingsProfileFirstUser.validateSettingsProfileIsShown(); + + // Validate that Chats Sidebar is not displayed on Settings Screen + await chatsSidebarFirstUser.sidebarChatsSection.waitForExist({ + reverse: true, + }); + }); + + it("Chat User A - Chats Sidebar is displayed again when opening Friends Screen", async () => { + // Validate on Friends Screen that sidebar is displayed + await settingsProfileFirstUser.goToFriends(); + await friendsScreenFirstUser.validateFriendsScreenIsShown(); + await chatsSidebarFirstUser.validateSidebarChatsIsShown(); + + // Return to chat + await chatsSidebarFirstUser.goToSidebarFirstChat(); + }); + + it("Chat User A - Sidebar - Validate Hamburger button and back buttons can hide or display the sidebar", async () => { + // Click on hamburger button and validate that Sidebar is hidden + await chatsLayoutFirstUser.clickOnHamburgerButton(); + + // Click on back button and validate that Sidebar is displayed again + await chatsLayoutFirstUser.clickOnBackButton(); + await chatsSidebarFirstUser.validateSidebarChatsIsShown(); + }); + + it("Chat User A - Sidebar - Context Menu - Delete chat", async () => { + // Open context menu and right click on Delete chat + await chatsSidebarFirstUser.openContextMenuOnSidebar("ChatUserB"); + await contextMenuSidebarFirstUser.selectChatsDeleteConversation(); + await chatsSidebarFirstUser.skeletalUser.waitForExist(); + }); + + it("Chat User A - Sidebar without messages sent displays No messages yet, sent one", async () => { + // Go to the current list of All friends and then open a Chat conversation with ChatUserA + await welcomeScreenFirstUser.goToFriends(); + await friendsScreenFirstUser.validateChatWithFriendButtonIsShown(); + await friendsScreenFirstUser.hoverOnChatWithFriendButton("ChatUserB"); + await friendsScreenFirstUser.clickOnChatWithFriend(); + await chatsLayoutFirstUser.validateChatLayoutIsShown(); + + // Validate that sidebar record is displayed with correct username and status + const sidebarChatUsername = + await chatsSidebarFirstUser.sidebarChatsUserNameValue; + await expect(sidebarChatUsername).toHaveTextContaining("ChatUserB"); + + const sidebarChatStatus = + await chatsSidebarFirstUser.sidebarChatsUserStatusValue; + await expect(sidebarChatStatus).toHaveTextContaining( + "No messages sent yet, send one!", + ); + }); + + it("Sidebar - Favorites - Add user to Favorites", async () => { + // Add user to favorites + await chatsTopbarFirstUser.addToFavorites(); + await favoritesSidebarFirstUser.validateFavoritesAreShown(); + + // Favorites Sidebar User bubble should be displayed with image + await favoritesSidebarFirstUser.validateFavoritesUserImage("ChatUserB"); + }); + + // Skipping test failing - needs research + xit("Sidebar - Favorites - Context Menu - Chat with user", async () => { + // Open context menu and right click on Chat with user + await favoritesSidebarFirstUser.goToFiles(); + await filesScreenFirstUser.validateFilesScreenIsShown(); + await favoritesSidebarFirstUser.openContextMenuOnFavoritesUser("ChatUserB"); + await favoritesSidebarFirstUser.clickOnContextMenuFavoritesChat(); + await chatsLayoutFirstUser.validateChatLayoutIsShown(); + await chatsInputFirstUser.typeMessageOnInput("Hi..."); + await chatsInputFirstUser.clearInputBar(); + }); + + it("Sidebar - Favorites - Context Menu - Remove user from Favorites", async () => { + // Open context menu and right click on Remove user from Favorites + await favoritesSidebarFirstUser.openContextMenuOnFavoritesUser("ChatUserB"); + await favoritesSidebarFirstUser.clickOnContextMenuFavoriteRemove(); + }); +} diff --git a/tests/specs/reusable-accounts/ChatUserA/09-group-chats-userA.spec.ts b/tests/specs/reusable-accounts/ChatUserA/09-group-chats-userA.spec.ts new file mode 100644 index 00000000000..0a573d553c1 --- /dev/null +++ b/tests/specs/reusable-accounts/ChatUserA/09-group-chats-userA.spec.ts @@ -0,0 +1,155 @@ +import "module-alias/register"; +import ChatsSidebar from "@screenobjects/chats/ChatsSidebar"; +import CreateGroupChat from "@screenobjects/chats/CreateGroupChat"; +import FilesScreen from "@screenobjects/files/FilesScreen"; +import InputBar from "@screenobjects/chats/InputBar"; +import Messages from "@screenobjects/chats/Messages"; +import SidebarSearch from "@screenobjects/chats/SidebarSearch"; +import Topbar from "@screenobjects/chats/Topbar"; +import { USER_A_INSTANCE } from "@helpers/constants"; +let chatsInputFirstUser = new InputBar(USER_A_INSTANCE); +let chatsMessagesFirstUser = new Messages(USER_A_INSTANCE); +let chatsSidebarFirstUser = new ChatsSidebar(USER_A_INSTANCE); +let chatsTopbarFirstUser = new Topbar(USER_A_INSTANCE); +let createGroupFirstUser = new CreateGroupChat(USER_A_INSTANCE); +let filesScreenFirstUser = new FilesScreen(USER_A_INSTANCE); +let sidebarSearchFirstUser = new SidebarSearch(USER_A_INSTANCE); + +export default async function groupChatTestsUserA() { + it("Chat User A - Create Group Chat button tooltip", async () => { + // Hover on create group chat button and validate tooltip is shown + await chatsSidebarFirstUser.hoverOnCreateGroupButton(); + }); + + it("Chat User A - Click on Create Group Chat and close modal", async () => { + // Open modal to create group chat + await chatsSidebarFirstUser.clickOnCreateGroupChat(); + await createGroupFirstUser.validateCreateGroupChatsIsShown(); + + // Click again on create group chat and modal will be closed + await chatsTopbarFirstUser.clickOnTopbar(); + await createGroupFirstUser.createGroupChatSection.waitForExist({ + reverse: true, + }); + }); + + it("Chat User A - Create Group Chat Modal contents", async () => { + // Open modal to create group chat + await chatsSidebarFirstUser.clickOnCreateGroupChat(); + await createGroupFirstUser.validateCreateGroupChatsIsShown(); + + // Validate contents + await createGroupFirstUser.createGroupChatButton.waitForExist(); + await createGroupFirstUser.friendsList.waitForExist(); + await createGroupFirstUser.groupNameInput.waitForExist(); + await createGroupFirstUser.userSearchInput.waitForExist(); + }); + + it("Chat User A - Attempt to create group chat with alphanumeric chars in name", async () => { + // Open modal to create group chat and type alphanumeric chars in name + await createGroupFirstUser.typeOnGroupName("@"); + await createGroupFirstUser.createGroupInputError.waitForExist(); + const inputErrorText = await createGroupFirstUser.createGroupInputErrorText; + await expect(inputErrorText).toHaveTextContaining( + "Not allowed character(s): @", + ); + await createGroupFirstUser.clearGroupNameInput(); + }); + + // Skipping test that sometimes fail in CI because Appium randomly jumps when typing into a different input field + xit("Chat User A - Attempt to create group chat with more than 64 chars in name", async () => { + // Open modal to create group chat and type more than 64 chars in name + await createGroupFirstUser.typeLongerTextInGroupName(); + await createGroupFirstUser.createGroupInputError.waitForExist(); + const inputErrorText = await createGroupFirstUser.createGroupInputErrorText; + await expect(inputErrorText).toHaveTextContaining( + "Maximum of 64 characters exceeded.", + ); + await createGroupFirstUser.clearGroupNameInput(); + }); + + it("Chat User A - Search bar - Look for non existing user", async () => { + // Open modal to create group chat and type non existing user + await createGroupFirstUser.typeOnUsersSearchInput("z"); + const numberOfUsersInList = + await createGroupFirstUser.getNumberOfUsersInListFromCreateGroup(); + await expect(numberOfUsersInList).toEqual(0); + await createGroupFirstUser.clearUserSearchInput(); + }); + + it("Chat User A - Create group chat with a valid participant", async () => { + // Open modal to create group chat and type valid participant and then create group chat + await createGroupFirstUser.typeOnGroupName("Test"); + await createGroupFirstUser.typeOnUsersSearchInput("Ch"); + await createGroupFirstUser.selectUserFromList("ChatUserB"); + await createGroupFirstUser.clickOnCreateGroupChat(); + await chatsSidebarFirstUser.waitForGroupToBeCreated("Test"); + }); + + it("Chat User A - Group Chat is displayed on local user sidebar", async () => { + // Validate group chat is displayed on local user sidebar and then go to group chat + const statusFromGroup = + await chatsSidebarFirstUser.getSidebarGroupStatus("Test"); + await expect(statusFromGroup).toHaveTextContaining( + "No messages sent yet, send one!", + ); + await chatsSidebarFirstUser.goToSidebarGroupChat("Test"); + await chatsTopbarFirstUser.validateTopbarExists(); + + // Validate topbar contents has correct name + const topbarUserName = chatsTopbarFirstUser.topbarUserNameValue; + await expect(topbarUserName).toHaveTextContaining("Test"); + + // Validate topbar contents has correct number of participants + const topbarUserStatus = chatsTopbarFirstUser.topbarUserStatusValue; + await expect(topbarUserStatus).toHaveTextContaining("Members (2)"); + }); + + it("Group Chat - User A sends a message in group chat", async () => { + // Send a message in group chat + await chatsInputFirstUser.typeMessageOnInput("Sup"); + await chatsInputFirstUser.clickOnSendMessage(); + await chatsMessagesFirstUser.waitForMessageSentToExist("Sup"); + await chatsInputFirstUser.typeMessageOnInput("test"); + await chatsInputFirstUser.clearInputBar(); + + // Validate text from message sent to the group + const textMessage = await chatsMessagesFirstUser.getLastMessageSentText(); + await expect(textMessage).toHaveTextContaining("Sup"); + }); + + it("Sidebar - Search string matching username and group and go to first result", async () => { + // Validate search results for a string matching a single user and a single group + await chatsTopbarFirstUser.goToFiles(); + await filesScreenFirstUser.validateFilesScreenIsShown(); + await chatsSidebarFirstUser.typeOnSidebarSearchInput("Ch"); + const searchResultsUsers = + await sidebarSearchFirstUser.getSidebarSearchResultsUsers(); + const searchResultsGroupsNotMatchingName = + await sidebarSearchFirstUser.getSidebarSearchResultsGroupsNotMatchingName(); + const searchResultsParticipantsInGroups = + await sidebarSearchFirstUser.getSidebarSearchResultsParticipantsInGroups(); + await expect(searchResultsUsers).toEqual(["ChatUserB"]); + await expect(searchResultsGroupsNotMatchingName).toEqual(["Test"]); + await expect(searchResultsParticipantsInGroups).toEqual(["ChatUserB"]); + await chatsSidebarFirstUser.clearSidebarSearchInput(); + }); + + it("Sidebar - Search Bar - Search for a string matching a single group chat", async () => { + // Validate search results for a string matching a single group chat + await chatsTopbarFirstUser.goToFiles(); + await filesScreenFirstUser.validateFilesScreenIsShown(); + await chatsSidebarFirstUser.typeOnSidebarSearchInput("Te"); + const searchResults = + await sidebarSearchFirstUser.getSidebarSearchResultsGroupsMatchingName(); + await expect(searchResults).toEqual(["Test"]); + await chatsSidebarFirstUser.clearSidebarSearchInput(); + }); + + it("Sidebar - Search Bar - Not matching results and then go to the group", async () => { + // Validate search results for a string not matching any group chat or user + await chatsSidebarFirstUser.typeOnSidebarSearchInput("z"); + await chatsSidebarFirstUser.clearSidebarSearchInput(); + await chatsSidebarFirstUser.goToSidebarGroupChat("Test"); + }); +} diff --git a/tests/specs/reusable-accounts/ChatUserA/10-group-chat-edit-userA.spec.ts b/tests/specs/reusable-accounts/ChatUserA/10-group-chat-edit-userA.spec.ts new file mode 100644 index 00000000000..17283b85491 --- /dev/null +++ b/tests/specs/reusable-accounts/ChatUserA/10-group-chat-edit-userA.spec.ts @@ -0,0 +1,140 @@ +import "module-alias/register"; +import EditGroup from "@screenobjects/chats/EditGroup"; +import ChatsSidebar from "@screenobjects/chats/ChatsSidebar"; +import Topbar from "@screenobjects/chats/Topbar"; +import { USER_A_INSTANCE } from "@helpers/constants"; +let chatsSidebarFirstUser = new ChatsSidebar(USER_A_INSTANCE); +let chatsTopbarFirstUser = new Topbar(USER_A_INSTANCE); +let editGroupFirstUser = new EditGroup(USER_A_INSTANCE); + +export default async function groupChatEditTestsUserA() { + it("Chat User A - Edit Group Chat button tooltip", async () => { + // Hover on edit group chat button and validate tooltip is shown + await chatsTopbarFirstUser.hoverOnEditGroupButton(); + + const tooltipText = await chatsTopbarFirstUser.topbarEditGroupTooltipText; + await expect(tooltipText).toHaveTextContaining("Edit Group"); + }); + + it("Chat User A - Click on Edit Group Chat and close modal", async () => { + // Open modal to edit group chat + await chatsTopbarFirstUser.editGroup(); + await editGroupFirstUser.validateEditGroupIsShown(); + await chatsTopbarFirstUser.editGroup(); + }); + + it("Edit Group - Group Name Edit - Contents displayed", async () => { + // Open edit group modal. Validate contents displayed + await chatsTopbarFirstUser.editGroup(); + await editGroupFirstUser.validateEditGroupIsShown(); + + await editGroupFirstUser.groupNameInput.waitForExist(); + await editGroupFirstUser.userInput.waitForExist(); + }); + + it("Edit Group - Attempt to change Group Name for a name containing non-alphanumeric characters", async () => { + // Type on group name input an invalid name and validate error message + await editGroupFirstUser.typeOnGroupNameInput("@"); + await editGroupFirstUser.groupNameInputError.waitForExist(); + + const inputErrorText = await editGroupFirstUser.groupNameInputErrorText; + await expect(inputErrorText).toHaveTextContaining( + "Not allowed character(s): @", + ); + + await editGroupFirstUser.clearGroupNameInput(); + }); + + // Skipping test due to input issue changing the cursor to a different input field + xit("Edit Group - Attempt to change Group Name for a name with more than 64 characters", async () => { + // Type on group name input a name with more than 64 characters and validate error message + await editGroupFirstUser.clickOnGroupNameInput(); + await editGroupFirstUser.typeOnGroupNameInput( + "12345678901234567890123456789012345678901234567890123456789012345678", + ); + + // Validate error message + await editGroupFirstUser.groupNameInputError.waitForExist(); + const inputErrorText = await editGroupFirstUser.groupNameInputErrorText; + await expect(inputErrorText).toHaveTextContaining( + "Maximum of 64 characters exceeded.", + ); + await editGroupFirstUser.clearGroupNameInput(); + }); + + it("Edit Group - Change Group Name for a valid name", async () => { + // Type on group name input a valid name and validate group name is changed correctly + await editGroupFirstUser.typeOnGroupNameInput("X"); + await chatsTopbarFirstUser.editGroup(); + await chatsSidebarFirstUser.waitForGroupToBeCreated("X"); + + // Validate group name was changed correctly on local side + const topbarFirstUserName = await chatsTopbarFirstUser.topbarUserNameValue; + await expect(topbarFirstUserName).toHaveTextContaining("X"); + await chatsSidebarFirstUser.waitForGroupToBeCreated("X"); + }); + + it("Edit Group - Contents displayed in add list are correct", async () => { + // Open edit group modal. Validate contents displayed in add list are correct + await chatsTopbarFirstUser.editGroup(); + await editGroupFirstUser.validateEditGroupIsShown(); + await editGroupFirstUser.clickOnAddMembers(); + await editGroupFirstUser.validateNothingHereIsDisplayed(); + }); + + it("Edit Group - Contents displayed in remove list are correct", async () => { + // Validate contents displayed in remove list are correct + await editGroupFirstUser.clickOnCurrentMembers(); + const currentList = await editGroupFirstUser.getParticipantsList(); + const expectedList = ["ChatUserB"]; + await expect(currentList).toEqual(expectedList); + }); + + it("Edit Group - Look for non existing user in Remove Users List", async () => { + // Type on search user input a non existing user and validate nothing here is displayed + await editGroupFirstUser.typeOnSearchUserInput("z"); + await editGroupFirstUser.validateNothingHereIsDisplayed(); + await editGroupFirstUser.clearSearchUserInput(); + }); + + it("Edit Group - Remove someone from the group", async () => { + // Type on search user input a valid user and then remove it from the group + await editGroupFirstUser.typeOnSearchUserInput("ChatUserB"); + await editGroupFirstUser.clickOnFirstRemoveButton(); + await editGroupFirstUser.validateNothingHereIsDisplayed(); + await chatsTopbarFirstUser.editGroup(); + await chatsTopbarFirstUser.validateTopbarExists(); + + const topbarUserStatus = chatsTopbarFirstUser.topbarUserStatusValue; + await expect(topbarUserStatus).toHaveTextContaining("Members (1)"); + }); + + it("Edit Group - Add Users List - Chat User B appears now in list", async () => { + // Open edit group modal. Validate contents displayed in add list are correct + await chatsTopbarFirstUser.editGroup(); + await editGroupFirstUser.validateEditGroupIsShown(); + await editGroupFirstUser.clickOnAddMembers(); + const currentList = await editGroupFirstUser.getParticipantsList(); + await expect(currentList).toEqual(["ChatUserB"]); + }); + + it("Edit Group - Look for non existing user in Add Users List", async () => { + // Type on search user input a non existing user and validate nothing here is displayed + await editGroupFirstUser.typeOnSearchUserInput("z"); + await editGroupFirstUser.validateNothingHereIsDisplayed(); + await editGroupFirstUser.clearSearchUserInput(); + }); + + it("Edit Group - Add someone to the group - Add Chat User B again", async () => { + // Type on search user input a valid user and then add it to the group + await editGroupFirstUser.typeOnSearchUserInput("ChatUserB"); + await editGroupFirstUser.clickOnFirstAddButton(); + await editGroupFirstUser.validateNothingHereIsDisplayed(); + await chatsTopbarFirstUser.editGroup(); + await chatsTopbarFirstUser.validateTopbarExists(); + + // Validate topbar contents has correct number of participants + const topbarUserStatus = await chatsTopbarFirstUser.topbarUserStatusValue; + await expect(topbarUserStatus).toHaveTextContaining("Members (2)"); + }); +} diff --git a/tests/specs/reusable-accounts/ChatUserA/11-group-chats-sidebar-userA.spec.ts b/tests/specs/reusable-accounts/ChatUserA/11-group-chats-sidebar-userA.spec.ts new file mode 100644 index 00000000000..178bbee48c5 --- /dev/null +++ b/tests/specs/reusable-accounts/ChatUserA/11-group-chats-sidebar-userA.spec.ts @@ -0,0 +1,119 @@ +import "module-alias/register"; +import ChatsSidebar from "@screenobjects/chats/ChatsSidebar"; +import ContextMenuSidebar from "@screenobjects/chats/ContextMenuSidebar"; +import EditGroup from "@screenobjects/chats/EditGroup"; +import FavoritesSidebar from "@screenobjects/chats/FavoritesSidebar"; +import FriendsScreen from "@screenobjects/friends/FriendsScreen"; +import Topbar from "@screenobjects/chats/Topbar"; +import { USER_A_INSTANCE } from "@helpers/constants"; +let chatsSidebarFirstUser = new ChatsSidebar(USER_A_INSTANCE); +let chatsTopbarFirstUser = new Topbar(USER_A_INSTANCE); +let contextMenuSidebarFirstUser = new ContextMenuSidebar(USER_A_INSTANCE); +let editGroupFirstUser = new EditGroup(USER_A_INSTANCE); +let favoritesSidebarFirstUser = new FavoritesSidebar(USER_A_INSTANCE); +let friendsScreenFirstUser = new FriendsScreen(USER_A_INSTANCE); + +export default async function groupChatSidebarTestsUserA() { + it("Group Chat - Add group to favorites", async () => { + // Leave Participants List screen + await chatsTopbarFirstUser.clickOnTopbar(); + + // Click on Favorites button for Group Chat + await chatsTopbarFirstUser.addToFavorites(); + await favoritesSidebarFirstUser.validateFavoritesAreShown(); + + // Favorites Sidebar should be displayed and showing the name of the group added to Favorites + // Favorites Sidebar User bubble should be displayed + await favoritesSidebarFirstUser.validateFavoritesUserImage("X"); + }); + + it("Group Chat - Remove group from favorites", async () => { + // Remove user from favorites and ensure that Favorites bar is hidden now + await chatsTopbarFirstUser.removeFromFavorites(); + }); + + it("Group Chats Testing - Go to another chat conversation", async () => { + // Go to another chat conversation + await chatsTopbarFirstUser.goToFriends(); + await friendsScreenFirstUser.validateFriendsScreenIsShown(); + await friendsScreenFirstUser.validateChatWithFriendButtonIsShown(); + await friendsScreenFirstUser.hoverOnChatWithFriendButton("ChatUserB"); + await friendsScreenFirstUser.clickOnChatWithFriend(); + await chatsTopbarFirstUser.validateTopbarExists(); + }); + + it("Group Chat - Sidebar - Any new messages received in group should appear in Sidebar", async () => { + // Validate Sidebar shows Group Name + await chatsSidebarFirstUser.validateUsernameDisplayed("X"); + + // Validate last message content from group is displayed on sidebar + await chatsSidebarFirstUser.validateLastMessageDisplayed("HelloGroup"); + + // Validate number of unread messages from the group is displayed on sidebar + await chatsSidebarFirstUser.validateNumberOfUnreadMessages("1"); + + // Validate time ago is displayed on sidebar for group chat + await chatsSidebarFirstUser.validateLastMessageTimeAgo(); + }); + + it("Group Chat - Sidebar - Context Menu - Clear Unreads", async () => { + // Open context menu on group chat and select Clear Unreads + await chatsSidebarFirstUser.openContextMenuOnGroupChat("X"); + await contextMenuSidebarFirstUser.selectChatsClearUnreads(); + await chatsSidebarFirstUser.validateNoUnreadMessages(); + }); + + it("Group Chat - Sidebar - Context Menu - Hide chat", async () => { + // Open context menu on group chat and select Hide Chat + await chatsSidebarFirstUser.openContextMenuOnGroupChat("X"); + await contextMenuSidebarFirstUser.selectChatsHideChat(); + await chatsSidebarFirstUser.validateSidebarChatIsNotDisplayed("X"); + }); + + it("Group Chat - Validate remote user received the message", async () => { + // Validate that message was received + await chatsSidebarFirstUser.waitForGroupToBeCreated("X"); + await chatsSidebarFirstUser.goToSidebarGroupChat("X"); + await chatsTopbarFirstUser.validateTopbarExists(); + }); + + it("Group Chat - Sidebar - If a user leaves a group, remote user will see the number of group members decreased", async () => { + // Now, go to the Group Chat and validate that User B is not part of it anymore + await chatsTopbarFirstUser.validateTopbarExists(); + + // Validate topbar contents has correct name + const topbarUserName = await chatsTopbarFirstUser.topbarUserNameValue; + await expect(topbarUserName).toHaveTextContaining("X"); + + // Validate topbar contents has correct number of participants + const topbarUserStatus = await chatsTopbarFirstUser.topbarUserStatusValue; + await expect(topbarUserStatus).toHaveTextContaining("Members (1)"); + }); + + it("Group Chat - Add Chat User B again to the group", async () => { + // Go to Edit Group and then add again Chat User B to the group + await chatsTopbarFirstUser.editGroup(); + await editGroupFirstUser.validateEditGroupIsShown(); + await editGroupFirstUser.clickOnAddMembers(); + await editGroupFirstUser.typeOnSearchUserInput("ChatUserB"); + await editGroupFirstUser.clickOnFirstAddButton(); + await editGroupFirstUser.validateNothingHereIsDisplayed(); + + // Validate topbar contents has correct number of participants + await chatsTopbarFirstUser.editGroup(); + await chatsTopbarFirstUser.validateTopbarExists(); + + // Validate topbar contents has correct number of participants + const topbarUserStatus = await chatsTopbarFirstUser.topbarUserStatusValue; + await expect(topbarUserStatus).toHaveTextContaining("Members (2)"); + }); + + it("Group Chat - Sidebar - Delete group", async () => { + // Delete the group + await chatsSidebarFirstUser.openContextMenuOnGroupChat("X"); + await contextMenuSidebarFirstUser.selectChatsDeleteGroup(); + + // Ensure that group was removed on local side + await chatsSidebarFirstUser.validateSidebarChatIsNotDisplayed("X"); + }); +} diff --git a/tests/specs/reusable-accounts/ChatUserB/03-message-context-menu-userB.spec.ts b/tests/specs/reusable-accounts/ChatUserB/03-message-context-menu-userB.spec.ts new file mode 100644 index 00000000000..dcd369ac2f9 --- /dev/null +++ b/tests/specs/reusable-accounts/ChatUserB/03-message-context-menu-userB.spec.ts @@ -0,0 +1,74 @@ +import "module-alias/register"; +import { USER_A_INSTANCE } from "@helpers/constants"; +import ContextMenu from "@screenobjects/chats/ContextMenu"; +import InputBar from "@screenobjects/chats/InputBar"; +import MessageGroup from "@screenobjects/chats/MessageGroup"; +import Messages from "@screenobjects/chats/Messages"; +let chatsContextMenuFirstUser = new ContextMenu(USER_A_INSTANCE); +let chatsInputFirstUser = new InputBar(USER_A_INSTANCE); +let chatsMessagesFirstUser = new Messages(USER_A_INSTANCE); +let chatsMessageGroupsFirstUser = new MessageGroup(USER_A_INSTANCE); + +export default async function messageContextMenuTestsUserB() { + it("Chat User B - Receive two messages from Chat User B", async () => { + // Assert messages received from Chat User B + await chatsMessagesFirstUser.waitForReceivingMessage("Two..."); + await chatsMessagesFirstUser.waitForReceivingMessage("Three..."); + }); + + it("Chat User B - Validate Message was deleted and is no longer visible in remote chat", async () => { + // With User B - Validate that last message is "Two..." + await chatsMessagesFirstUser.waitForReceivingMessage("Two..."); + + // With User B - Ensure that message "three.." was deleted + await chatsMessagesFirstUser.waitForMessageToBeDeleted("Three..."); + }); + + it("Chat User B - Receive reaction in sent message", async () => { + await chatsInputFirstUser.clickOnInputBar(); + await chatsInputFirstUser.typeMessageOnInput("Hello"); + await chatsInputFirstUser.clearInputBar(); + + // Validate reactions received on sent message + await chatsMessageGroupsFirstUser.waitUntilEmojiReactionRemoteExists("๐Ÿ‘Ž"); + const reaction = + await chatsMessageGroupsFirstUser.getLastMessageSentRemoteReactions(); + await expect(reaction.includes("๐Ÿ‘Ž 1")).toEqual(true); + }); + + it("Chat User B - Receive reaction in received message", async () => { + // Validate reactions received on sent message + await chatsMessageGroupsFirstUser.waitUntilEmojiReactionRemoteExists("๐Ÿ––"); + const reactions = + await chatsMessageGroupsFirstUser.getLastMessageReceivedRemoteReactions(); + await expect(reactions.includes("๐Ÿ–– 1")).toEqual(true); + await expect(reactions.includes("๐Ÿ˜‚ 1")).toEqual(true); + }); + + it("Chat User B - Both users can react with the same emoji to a message", async () => { + // React with ๐Ÿ‘Ž emoji + await chatsMessagesFirstUser.openContextMenuOnLastSent(); + await chatsContextMenuFirstUser.validateContextMenuIsOpen(); + await chatsContextMenuFirstUser.clickOnThirdReaction(); + + // Validate reaction is displayed correctly + await chatsMessageGroupsFirstUser.waitUntilEmojiReactionSelfExists("๐Ÿ‘Ž"); + const reaction = + await chatsMessageGroupsFirstUser.getLastMessageSentSelfReactions(); + await expect(reaction.includes("๐Ÿ‘Ž 2")).toEqual(true); + }); + + it("Chat User B - Users can add a new reaction to a message already containing reactions", async () => { + // React with ๐Ÿ‘ emoji + await chatsMessagesFirstUser.openContextMenuOnLastSent(); + await chatsContextMenuFirstUser.validateContextMenuIsOpen(); + await chatsContextMenuFirstUser.clickOnFourthReaction(); + + // Validate reaction is displayed correctly + await chatsMessageGroupsFirstUser.waitUntilEmojiReactionSelfExists("๐Ÿ‘"); + const reaction = + await chatsMessageGroupsFirstUser.getLastMessageSentSelfReactions(); + await expect(reaction.includes("๐Ÿ‘Ž 2")).toEqual(true); + await expect(reaction.includes("๐Ÿ‘ 1")).toEqual(true); + }); +} diff --git a/tests/specs/reusable-accounts/ChatUserB/04-message-input-userB.spec.ts b/tests/specs/reusable-accounts/ChatUserB/04-message-input-userB.spec.ts new file mode 100644 index 00000000000..7f5510208a2 --- /dev/null +++ b/tests/specs/reusable-accounts/ChatUserB/04-message-input-userB.spec.ts @@ -0,0 +1,68 @@ +import "module-alias/register"; +import { USER_A_INSTANCE } from "@helpers/constants"; +import ChatsLayout from "@screenobjects/chats/ChatsLayout"; +import Messages from "@screenobjects/chats/Messages"; +let chatsMessagesFirstUser = new Messages(USER_A_INSTANCE); +let chatsLayoutFirstUser = new ChatsLayout(USER_A_INSTANCE); + +export default async function messageInputTestsUserB() { + it("Chat Input Text - Validate messages with bold markdowns were received in expected format", async () => { + // With Chat User B, validate message with with ** markdown was received in bolds + await chatsMessagesFirstUser.waitForReceivingMessage("Bolds1"); + + // With Chat User B, validate message with with __ markdown was received in bolds + await chatsMessagesFirstUser.waitForReceivingMessage("Bolds2"); + }); + + // Skipping test that is failing often on CI - Requires investigation to improve execution + xit("Chat Input Text - Validate message with code markdown is received in expected format", async () => { + // With Chat User B, validate code message was received and is displayed correctly + await chatsMessagesFirstUser.waitForReceivingCodeMessage("JavaScript"); + const codeMessageTextReceived = + await chatsMessagesFirstUser.getLastMessageReceivedCodeMessage(); + await expect(codeMessageTextReceived).toEqual("let a = 1;"); + }); + + it("Chat Input Text - Validate messages with links were received correctly", async () => { + // With Chat User B, validate message with URL starting with https:// was received as link + await chatsMessagesFirstUser.waitForReceivingLink("https://www.google.com"); + + // With Chat User B, validate message with URL starting with www. was received as link + await chatsMessagesFirstUser.waitForReceivingLink("www.apple.com"); + + // With Chat User B, validate message with URL starting with http:// was received as link + await chatsMessagesFirstUser.waitForReceivingLink( + "http://www.satellite.im", + ); + }); + + it("Chat User - Chat Messages containing links contents on remote side", async () => { + // Validate link embed contents on chat message + const linkEmbedReceived = + await chatsMessagesFirstUser.getLastMessageReceivedLinkEmbed(); + const linkEmbedReceivedDetailsText = + await chatsMessagesFirstUser.getLastMessageReceivedLinkEmbedDetailsText(); + const linkEmbedReceivedIcon = + await chatsMessagesFirstUser.getLastMessageReceivedLinkEmbedIcon(); + const linkEmbedReceivedIconTitle = + await chatsMessagesFirstUser.getLastMessageReceivedLinkEmbedIconTitle(); + + await linkEmbedReceived.waitForExist(); + await expect(linkEmbedReceivedDetailsText).toHaveTextContaining( + "P2P Chat, Voice & Video Open-source, stored on IPFS. End to end encryption... trackers not included.", + ); + await linkEmbedReceivedIcon.waitForExist(); + await linkEmbedReceivedIconTitle.waitForExist(); + }); + + // Skipping test failing on because the typing indicator is gone before the test can validate it + xit("Validate Typing Indicator is displayed if remote user is typing", async () => { + // Switch to second user and validate that Typing Indicator is displayed + await chatsLayoutFirstUser.typingIndicator.waitForExist({ + timeout: 30000, + }); + await expect( + chatsLayoutFirstUser.typingIndicatorTextValue, + ).toHaveTextContaining("ChatUserA is typing"); + }); +} diff --git a/tests/specs/reusable-accounts/ChatUserB/05-message-attachments-userB.spec.ts b/tests/specs/reusable-accounts/ChatUserB/05-message-attachments-userB.spec.ts new file mode 100644 index 00000000000..693866dc802 --- /dev/null +++ b/tests/specs/reusable-accounts/ChatUserB/05-message-attachments-userB.spec.ts @@ -0,0 +1,176 @@ +import "module-alias/register"; +import { USER_A_INSTANCE } from "@helpers/constants"; +import ComposeAttachment from "@screenobjects/chats/ComposeAttachment"; +import FilesScreen from "@screenobjects/files/FilesScreen"; +import InputBar from "@screenobjects/chats/InputBar"; +import Messages from "@screenobjects/chats/Messages"; +import SendFiles from "@screenobjects/chats/SendFiles"; +let chatsAttachmentFirstUser = new ComposeAttachment(USER_A_INSTANCE); +let chatsInputFirstUser = new InputBar(USER_A_INSTANCE); +let chatsMessagesFirstUser = new Messages(USER_A_INSTANCE); +let filesScreenFirstUser = new FilesScreen(USER_A_INSTANCE); +let sendFilesFirstUser = new SendFiles(USER_A_INSTANCE); + +export default async function messageAttachmentsTestsUserB() { + it("Send files from Browse Files - No files are displayed on modal and user can close modal", async () => { + // Go to upload button and then select Browser Files (from Uplink storage) + await chatsInputFirstUser.openUploadFilesFromStorage(); + await sendFilesFirstUser.validateSendFilesModalIsShown(); + await sendFilesFirstUser.validateNoFilesAvailableIsShown(); + + // Click outside of the modal to close it, in this case on the send message button + await sendFilesFirstUser.clickOnCloseModal(); + }); + + it("Send files from Browse Files - Upload an image on Files to run tests", async () => { + // Go to Files Screen andand upload an image file before starting + await chatsInputFirstUser.goToFiles(); + await filesScreenFirstUser.validateFilesScreenIsShown(); + await filesScreenFirstUser.uploadFile("./tests/fixtures/banner.jpg"); + await filesScreenFirstUser.validateFileOrFolderExist("banner.jpg"); + }); + + it("Send files from Browse Files - Upload a txt file in a different folder", async () => { + // Create a new folder and enter on it + await filesScreenFirstUser.createFolder("testfolder01"); + await filesScreenFirstUser.validateFileOrFolderExist("testfolder01"); + await filesScreenFirstUser.clickOnFileOrFolder("testfolder01"); + + // Upload one time the testfile.txt file + await filesScreenFirstUser.uploadFile("./tests/fixtures/testfile.txt"); + await filesScreenFirstUser.validateFileOrFolderExist("testfile.txt"); + + // Return to chat screen + await filesScreenFirstUser.goToMainScreen(); + }); + + it("Send files from Browse Files - Thumbnails are displayed on modal", async () => { + // Open modal to send files from storage + await chatsInputFirstUser.openUploadFilesFromStorage(); + await sendFilesFirstUser.validateSendFilesModalIsShown(); + + // Go to Home Folder and validate thumbnail for file is shown + await sendFilesFirstUser.clickOnHomeFolderCrumb(); + await filesScreenFirstUser.validateFileOrFolderExist("banner.jpg"); + await sendFilesFirstUser.validateThumbnailIsShown("banner.jpg"); + }); + + // Skipping test because it takes too much time for execution + xit("Send files from Browse Files - User can navigate through folders and to home", async () => { + // Navigate to testfolder01 and ensure thumbnail from testfile.txt is shown + await sendFilesFirstUser.clickOnFileOrFolder("testfolder01"); + await filesScreenFirstUser.validateFileOrFolderExist("testfile.txt"); + await sendFilesFirstUser.validateThumbnailIsShown("testfile.txt"); + + // Navigate to home folder and ensure thumbnail from banner.jpg is shown + await sendFilesFirstUser.clickOnHomeFolderCrumb(); + await filesScreenFirstUser.validateFileOrFolderExist("banner.jpg"); + await sendFilesFirstUser.validateThumbnailIsShown("banner.jpg"); + }); + + it("Send files from Browse Files - Go to files button redirects to Files", async () => { + // Click on Go To Files button and validate User is redirected to Files Screen + await sendFilesFirstUser.clickOnGoToFiles(); + await filesScreenFirstUser.validateFilesScreenIsShown(); + + // Return to Chat Screen and open again the Send Files from Storage modal + await filesScreenFirstUser.goToMainScreen(); + await chatsInputFirstUser.openUploadFilesFromStorage(); + await sendFilesFirstUser.validateSendFilesModalIsShown(); + }); + + it("Send files from Browse Files - Send files button shows 0/8 files if no files are selected", async () => { + // When no files are selected, Send Files button should display 0/8 File(s) + await sendFilesFirstUser.validateSendFilesButtonText("Send 0/8 File(s)"); + }); + + it("Send files from Browse Files - User cannot click on send files if no files are selected", async () => { + // Click on Send files button without any files selected + await sendFilesFirstUser.clickOnSendFilesButton(); + + // Ensure that Send Files Modal is still displayed + await sendFilesFirstUser.validateSendFilesModalIsShown(); + }); + + it("Send files from Browse Files - Send files counter is updated", async () => { + // Select one file from root folder and ensure Send Files button displays 1/8 File(s) + await sendFilesFirstUser.clickOnFileOrFolder("banner.jpg"); + await sendFilesFirstUser.validateSendFilesButtonText("Send 1/8 File(s)"); + }); + + it("Send files from Browse Files - Files selected will be displayed on Compose Attachment", async () => { + // Send the only image file previously selected + await sendFilesFirstUser.clickOnSendFilesButton(); + + // Validate file is displayed on Compose Attachment + // Validate compose attachments displays the files to be uploaded before sending the message + await chatsAttachmentFirstUser.validateComposeAttachmentsIsShown(); + + // Obtain the list of attachments added to Compose Attachment + await chatsAttachmentFirstUser.validateAttachmentWithFileNameIsAdded( + "banner.jpg", + true, + ); + }); + + it("Send files from Browse Files - Message sent with attachments is shown on local side", async () => { + // Type a text message and send it + await chatsInputFirstUser.typeMessageOnInput("Attached"); + await chatsInputFirstUser.pressEnterKeyOnInputBar(); + + // Ensure that message sent with attached file is displayed on local side + await chatsMessagesFirstUser.waitForMessageSentToExist("Attached"); + + await chatsMessagesFirstUser.chatMessageFileEmbedLocal.waitForExist(); + + // Validate text from message containing attachment + const textMessage = await chatsMessagesFirstUser.getLastMessageSentText(); + await expect(textMessage).toHaveTextContaining("Attached"); + }); + + it("Send File from Add Files - Select a file and send message with attachment", async () => { + // Click on upload button and attach a file to compose attachment + await chatsInputFirstUser.uploadFileFromLocalDisk( + "./tests/fixtures/testfile.txt", + ); + + // Validate contents on Compose Attachments are displayed + await chatsAttachmentFirstUser.composeAttachmentsFileEmbed.waitForExist(); + + // Type a text message and send it + await chatsInputFirstUser.typeMessageOnInput("Attached2"); + await chatsInputFirstUser.pressEnterKeyOnInputBar(); + await chatsMessagesFirstUser.waitForMessageSentToExist("Attached2"); + }); + + it("Send Files on Chats - Message Sent With Attachment - Attachment Contents", async () => { + await chatsMessagesFirstUser.chatMessageFileEmbedLocal.waitForExist(); + + // Validate text from message containing attachment + const textMessage = await chatsMessagesFirstUser.getLastMessageSentText(); + await expect(textMessage).toHaveTextContaining("Attached2"); + + // Validate file metadata is displayed correctly on last chat message sent + const fileMeta = await chatsMessagesFirstUser.getLastMessageSentFileMeta(); + await expect(fileMeta).toHaveTextContaining("47 B"); + + // Validate filename is displayed correctly on last chat message sent + const fileName = await chatsMessagesFirstUser.getLastMessageSentFileName(); + await expect(fileName).toHaveTextContaining("testfile.txt"); + + // Validate file icon is displayed correctly on last chat message sent + const fileIcon = await chatsMessagesFirstUser.getLastMessageSentFileIcon(); + await fileIcon.waitForExist(); + + // Validate file download button is displayed correctly on last chat message sent + await chatsMessagesFirstUser.hoverOnLastFileSent(); + const fileDownloadButton = + await chatsMessagesFirstUser.getLastMessageSentDownloadButton(); + await fileDownloadButton.waitForExist(); + }); + + it("Chat Messages with Files - Local user can download file sent", async () => { + // Download latest image file received + await chatsMessagesFirstUser.downloadLastSentFile(".txt"); + }); +} diff --git a/tests/specs/reusable-accounts/ChatUserB/06-quick-profile-userB.spec.ts b/tests/specs/reusable-accounts/ChatUserB/06-quick-profile-userB.spec.ts new file mode 100644 index 00000000000..0c595aef05a --- /dev/null +++ b/tests/specs/reusable-accounts/ChatUserB/06-quick-profile-userB.spec.ts @@ -0,0 +1,68 @@ +import "module-alias/register"; +import { USER_A_INSTANCE } from "@helpers/constants"; +import FriendsScreen from "@screenobjects/friends/FriendsScreen"; +import InputBar from "@screenobjects/chats/InputBar"; +import Messages from "@screenobjects/chats/Messages"; +import Topbar from "@screenobjects/chats/Topbar"; +import WelcomeScreen from "@screenobjects/welcome-screen/WelcomeScreen"; + +let chatsInputFirstUser = new InputBar(USER_A_INSTANCE); +let chatsMessagesFirstUser = new Messages(USER_A_INSTANCE); +let chatsTopbarFirstUser = new Topbar(USER_A_INSTANCE); +let friendsScreenFirstUser = new FriendsScreen(USER_A_INSTANCE); +let welcomeScreenFirstUser = new WelcomeScreen(USER_A_INSTANCE); + +export default async function quickProfileTestsUserB() { + it("Chat User B - Send message to User A", async () => { + await chatsInputFirstUser.clickOnInputBar(); + await chatsInputFirstUser.typeMessageOnInput("click..."); + await chatsInputFirstUser.clickOnSendMessage(); + await chatsMessagesFirstUser.waitForMessageSentToExist("click..."); + }); + + it("Chat User B - Validate friendship was removed", async () => { + // With User B - Go to Friends and wait for User A to remove friendship with User B + await welcomeScreenFirstUser.goToFriends(); + await friendsScreenFirstUser.validateFriendsScreenIsShown(); + }); + + it("Chat User B - Validate that User A is now a friend", async () => { + // With User B - Go to pending requests list, wait for receiving the friend request and accept it + await friendsScreenFirstUser.hoverOnFriendsButton(); + await friendsScreenFirstUser.goToFriends(); + await friendsScreenFirstUser.validateFriendsScreenIsShown(); + await friendsScreenFirstUser.hoverOnPendingListButton(); + await friendsScreenFirstUser.goToPendingFriendsList(); + await friendsScreenFirstUser.validateIncomingListIsShown(); + await friendsScreenFirstUser.acceptIncomingRequest("ChatUserA"); + + // Return to Friends List + await friendsScreenFirstUser.goToAllFriendsList(); + await friendsScreenFirstUser.validateAllFriendsListIsShown(); + + // Validate friend is now on all friends list + await friendsScreenFirstUser.validateAllFriendsListIsNotEmpty(); + }); + + it("Chat User B - Send message to User B", async () => { + // Go to the current list of All friends and then open a Chat conversation with ChatUserA + await friendsScreenFirstUser.validateChatWithFriendButtonIsShown(); + await friendsScreenFirstUser.hoverOnChatWithFriendButton("ChatUserA"); + await friendsScreenFirstUser.clickOnChatWithFriend(); + + // Validate that Topbar is displayed + await chatsTopbarFirstUser.validateTopbarExists(); + + // Send message to Chat User B + await chatsInputFirstUser.typeMessageOnInput("Accepted..."); + await chatsInputFirstUser.clickOnSendMessage(); + await chatsMessagesFirstUser.waitForMessageSentToExist("Accepted..."); + }); + + it("Chat User B - Validate that User A blocked User B", async () => { + // With User B - Go to Friends and wait for User A to remove friendship with User B + await chatsInputFirstUser.goToFriends(); + await friendsScreenFirstUser.validateFriendsScreenIsShown(); + await friendsScreenFirstUser.waitUntilFriendIsRemoved("ChatUserA"); + }); +} diff --git a/tests/specs/reusable-accounts/ChatUserB/07-sidebar-chats-userB.spec.ts b/tests/specs/reusable-accounts/ChatUserB/07-sidebar-chats-userB.spec.ts new file mode 100644 index 00000000000..423631c6d0f --- /dev/null +++ b/tests/specs/reusable-accounts/ChatUserB/07-sidebar-chats-userB.spec.ts @@ -0,0 +1,73 @@ +import "module-alias/register"; +import { USER_A_INSTANCE } from "@helpers/constants"; +import ChatsLayout from "@screenobjects/chats/ChatsLayout"; +import InputBar from "@screenobjects/chats/InputBar"; +import Messages from "@screenobjects/chats/Messages"; +import FriendsScreen from "@screenobjects/friends/FriendsScreen"; +import WelcomeScreen from "@screenobjects/welcome-screen/WelcomeScreen"; +let chatsInputFirstUser = new InputBar(USER_A_INSTANCE); +let chatsLayoutFirstUser = new ChatsLayout(USER_A_INSTANCE); +let chatsMessagesFirstUser = new Messages(USER_A_INSTANCE); +let friendsScreenFirstUser = new FriendsScreen(USER_A_INSTANCE); +let welcomeScreenFirstUser = new WelcomeScreen(USER_A_INSTANCE); + +export default async function sidebarChatsTestsUserB() { + it("Chat User B - Validate button badge displays the number of incoming requests", async () => { + // Go to pending requests list, wait for receiving the friend request and accept it + await friendsScreenFirstUser.goToFriends(); + await friendsScreenFirstUser.validateFriendsScreenIsShown(); + await friendsScreenFirstUser.hoverOnPendingListButton(); + await friendsScreenFirstUser.goToPendingFriendsList(); + await friendsScreenFirstUser.validateIncomingListIsShown(); + await friendsScreenFirstUser.waitUntilFriendRequestIsReceived(); + + // Validate that button badge displays the number of incoming requests + await friendsScreenFirstUser.validateFriendsButtonBadgeIsShown; + const friendsButtonBadgeText = + await friendsScreenFirstUser.getValueFromFriendsButtonBadge(); + await expect(friendsButtonBadgeText).toEqual("1"); + }); + + it("Chat User B - Accept incoming request", async () => { + // Accept incoming request + await friendsScreenFirstUser.acceptIncomingRequest("ChatUserA"); + await friendsScreenFirstUser.acceptFriendRequestButton.waitForExist({ + reverse: true, + }); + + // Return to Friends List + await friendsScreenFirstUser.goToAllFriendsList(); + await friendsScreenFirstUser.validateAllFriendsListIsShown(); + }); + + it("Chat User B - Send message to User A", async () => { + // Go to the current list of All friends and then open a Chat conversation with ChatUserA + await friendsScreenFirstUser.validateChatWithFriendButtonIsShown(); + await friendsScreenFirstUser.hoverOnChatWithFriendButton("ChatUserA"); + await friendsScreenFirstUser.clickOnChatWithFriend(); + await chatsLayoutFirstUser.validateChatLayoutIsShown(); + + // Send message with markdown to Chat User B + await chatsInputFirstUser.typeMessageOnInput("__hello__"); + await chatsInputFirstUser.clickOnSendMessage(); + await chatsMessagesFirstUser.waitForMessageSentToExist("hello"); + }); + + it("Chat User B - Validate message was received", async () => { + // With User B - Wait until message is received + await chatsMessagesFirstUser.waitForReceivingMessage("Hi..."); + }); + + it("Chat User B - Sidebar - Wait for receiving a a new message", async () => { + // With User B - Wait until message is received + await chatsMessagesFirstUser.waitForReceivingMessage("Hi..."); + const latestMessage = + await chatsMessagesFirstUser.getLastMessageReceivedText(); + await expect(latestMessage).toHaveTextContaining("Hi..."); + }); + + it("Chat User B - Sidebar - If user deletes chat on remote side, it will be removed on local side as well", async () => { + // After user deletes chat conversation on remote side, chat is deleted on local side and Welcome Image displayed again + await welcomeScreenFirstUser.skeletalUser.waitForExist(); + }); +} diff --git a/tests/specs/reusable-accounts/ChatUserB/08-group-chats-userB.spec.ts b/tests/specs/reusable-accounts/ChatUserB/08-group-chats-userB.spec.ts new file mode 100644 index 00000000000..31f5b7be7ec --- /dev/null +++ b/tests/specs/reusable-accounts/ChatUserB/08-group-chats-userB.spec.ts @@ -0,0 +1,46 @@ +import "module-alias/register"; +import ChatsSidebar from "@screenobjects/chats/ChatsSidebar"; +import Messages from "@screenobjects/chats/Messages"; +import Topbar from "@screenobjects/chats/Topbar"; +import { USER_A_INSTANCE } from "@helpers/constants"; +let chatsMessagesFirstUser = new Messages(USER_A_INSTANCE); +let chatsSidebarFirstUser = new ChatsSidebar(USER_A_INSTANCE); +let chatsTopbarFirstUser = new Topbar(USER_A_INSTANCE); + +export default async function groupChatTestsUserB() { + it("User B - Group Chat is displayed on remote participant users sidebar", async () => { + // Validate group chat is displayed on remote participant users sidebar and then go to group chat + await chatsSidebarFirstUser.waitForGroupToBeCreated("Test"); + const statusFromGroupOnUserB = + await chatsSidebarFirstUser.getSidebarGroupStatus("Test"); + await expect(statusFromGroupOnUserB).toHaveTextContaining( + "No messages sent yet, send one!", + ); + await chatsSidebarFirstUser.goToSidebarGroupChat("Test"); + + await chatsTopbarFirstUser.validateTopbarExists(); + + const topbarUserName = await chatsTopbarFirstUser.topbarUserNameValue; + await expect(topbarUserName).toHaveTextContaining("Test"); + + const topbarUserStatus = await chatsTopbarFirstUser.topbarUserStatusValue; + await expect(topbarUserStatus).toHaveTextContaining("Members (2)"); + await chatsSidebarFirstUser.goToSidebarChat("ChatUserA"); + + await chatsTopbarFirstUser.validateTopbarExists(); + }); + + it("Group Chat - User B receives the message in group chat", async () => { + // Validate message is received in group chat + await chatsSidebarFirstUser.goToSidebarGroupChat("Test"); + await chatsMessagesFirstUser.waitForReceivingMessage("Sup"); + }); + + it("Group Chat - User B - Group is displayed", async () => { + // Validate search results for a string not matching any group chat or user + await chatsTopbarFirstUser.validateTopbarExists(); + + const topbarUserName = await chatsTopbarFirstUser.topbarUserNameValue; + await expect(topbarUserName).toHaveTextContaining("Test"); + }); +} diff --git a/tests/specs/reusable-accounts/ChatUserB/09-group-chat-edit-userB.spec.ts b/tests/specs/reusable-accounts/ChatUserB/09-group-chat-edit-userB.spec.ts new file mode 100644 index 00000000000..e09f6d0f72c --- /dev/null +++ b/tests/specs/reusable-accounts/ChatUserB/09-group-chat-edit-userB.spec.ts @@ -0,0 +1,48 @@ +import "module-alias/register"; +import ChatsSidebar from "@screenobjects/chats/ChatsSidebar"; +import FilesScreen from "@screenobjects/files/FilesScreen"; +import Topbar from "@screenobjects/chats/Topbar"; +import WelcomeScreen from "@screenobjects/welcome-screen/WelcomeScreen"; +import { USER_A_INSTANCE } from "@helpers/constants"; +let chatsSidebarFirstUser = new ChatsSidebar(USER_A_INSTANCE); +let chatsTopbarFirstUser = new Topbar(USER_A_INSTANCE); +let filesScreenFirstUser = new FilesScreen(USER_A_INSTANCE); +let welcomeScreenFirstUser = new WelcomeScreen(USER_A_INSTANCE); + +export default async function groupChatEditTestsUserB() { + it("Chat User B - You are not the group creator tooltip is displayed", async () => { + // Validate tooltip is shown + await chatsTopbarFirstUser.hoverOnEditGroupButton(); + + const tooltipText = await chatsTopbarFirstUser.viewGroupTooltipText; + await expect(tooltipText).toHaveTextContaining("View Group"); + }); + + it("Edit Group - Validate group name was changed correctly on remote side", async () => { + // Validate group name was changed correctly on remote side + await chatsSidebarFirstUser.waitForGroupToBeCreated("X"); + const topbarSecondUserName = await chatsTopbarFirstUser.topbarUserNameValue; + await expect(topbarSecondUserName).toHaveTextContaining("X"); + }); + + it("Edit Group - Validate remote user was correctly removed from the group chat", async () => { + // Validate that remote user was removed from the group correctly + await chatsSidebarFirstUser.waitForGroupToBeDeleted("X"); + await welcomeScreenFirstUser.validateWelcomeScreenIsShown(); + }); + + it("Edit Group - Ensure that Chat User B was added back to the group", async () => { + // Validate that User B was added back to the group chat + await chatsSidebarFirstUser.goToFiles(); + await filesScreenFirstUser.validateFilesScreenIsShown(); + await filesScreenFirstUser.goToMainScreen(); + await chatsSidebarFirstUser.validateSidebarChatsIsShown(); + await chatsSidebarFirstUser.waitForGroupToBeCreated("X"); + await chatsSidebarFirstUser.goToSidebarGroupChat("X"); + await chatsTopbarFirstUser.validateTopbarExists(); + + // Validate topbar contents has correct name + const topbarUserStatus = await chatsTopbarFirstUser.topbarUserStatusValue; + await expect(topbarUserStatus).toHaveTextContaining("Members (2)"); + }); +} diff --git a/tests/specs/reusable-accounts/ChatUserB/10-group-chats-sidebar-userB.spec.ts b/tests/specs/reusable-accounts/ChatUserB/10-group-chats-sidebar-userB.spec.ts new file mode 100644 index 00000000000..12760b99fc1 --- /dev/null +++ b/tests/specs/reusable-accounts/ChatUserB/10-group-chats-sidebar-userB.spec.ts @@ -0,0 +1,57 @@ +import "module-alias/register"; +import ChatsSidebar from "@screenobjects/chats/ChatsSidebar"; +import ContextMenuSidebar from "@screenobjects/chats/ContextMenuSidebar"; +import FilesScreen from "@screenobjects/files/FilesScreen"; +import InputBar from "@screenobjects/chats/InputBar"; +import Messages from "@screenobjects/chats/Messages"; +import Topbar from "@screenobjects/chats/Topbar"; +import { USER_A_INSTANCE } from "@helpers/constants"; +let chatsInputFirstUser = new InputBar(USER_A_INSTANCE); +let chatsMessagesFirstUser = new Messages(USER_A_INSTANCE); +let chatsSidebarFirstUser = new ChatsSidebar(USER_A_INSTANCE); +let chatsTopbarFirstUser = new Topbar(USER_A_INSTANCE); +let contextMenuSidebarFirstUser = new ContextMenuSidebar(USER_A_INSTANCE); +let filesScreenFirstUser = new FilesScreen(USER_A_INSTANCE); + +export default async function groupChatSidebarTestsUserB() { + it("Group Chat - Send message to the group with User B", async () => { + // Send message to the group + await chatsInputFirstUser.typeMessageOnInput("HelloGroup"); + await chatsInputFirstUser.clickOnSendMessage(); + await chatsMessagesFirstUser.waitForMessageSentToExist("HelloGroup"); + }); + + it("Group Chat - Send another message to show again the group chat", async () => { + // Send message to the group + await chatsInputFirstUser.typeMessageOnInput("Hey!"); + await chatsInputFirstUser.clickOnSendMessage(); + await chatsMessagesFirstUser.waitForMessageSentToExist("Hey!"); + }); + + it("Group Chat - Sidebar - Leave group", async () => { + // Leave group chat + await chatsSidebarFirstUser.openContextMenuOnGroupChat("X"); + await contextMenuSidebarFirstUser.selectChatsLeaveGroup(); + await chatsSidebarFirstUser.validateSidebarChatIsNotDisplayed("X"); + }); + + it("Group Chat - Ensure in remote side that user was added again to the group", async () => { + // Ensure that user was added again to the group + await chatsSidebarFirstUser.goToFiles(); + await filesScreenFirstUser.validateFilesScreenIsShown(); + await filesScreenFirstUser.goToMainScreen(); + await chatsSidebarFirstUser.validateSidebarChatsIsShown(); + await chatsSidebarFirstUser.waitForGroupToBeCreated("X"); + await chatsSidebarFirstUser.goToSidebarGroupChat("X"); + await chatsTopbarFirstUser.validateTopbarExists(); + + // Validate topbar contents has correct name + const topbarUserName = await chatsTopbarFirstUser.topbarUserNameValue; + await expect(topbarUserName).toHaveTextContaining("X"); + }); + + it("Group Chat - Sidebar - Deleted group is not shown on remote side", async () => { + // Ensure that group was removed on this side too + await chatsSidebarFirstUser.validateSidebarChatIsNotDisplayed("X"); + }); +} diff --git a/tests/suites/Chats/02-ChatsUserA.suite.ts b/tests/suites/Chats/02-ChatsUserA.suite.ts index b7b40e3b33f..b9694a554f1 100644 --- a/tests/suites/Chats/02-ChatsUserA.suite.ts +++ b/tests/suites/Chats/02-ChatsUserA.suite.ts @@ -1,6 +1,26 @@ import "module-alias/register"; import mainChatsTestsUserA from "@specs/reusable-accounts/ChatUserA/01-main-chats-userA.spec"; +import repliesTestsUserA from "@specs/reusable-accounts/ChatUserA/02-chat-replies-userA.spec"; +import messageContextMenuTestsUserA from "@specs/reusable-accounts/ChatUserA/03-message-context-menu-userA.spec"; +import messageInputTestsUserA from "@specs/reusable-accounts/ChatUserA/04-message-input-userA.spec"; +import messageAttachmentsTestsUserA from "@specs/reusable-accounts/ChatUserA/05-message-attachments-userA.spec"; +import chatTopbarTestsUserA from "@specs/reusable-accounts/ChatUserA/06-chat-topbar-userA.spec"; +import quickProfileTestsUserA from "@specs/reusable-accounts/ChatUserA/07-quick-profile-userA.spec"; +import sidebarChatsTestsUserA from "@specs/reusable-accounts/ChatUserA/08-sidebar-chats-userA.spec"; +import groupChatTestsUserA from "@specs/reusable-accounts/ChatUserA/09-group-chats-userA.spec"; +import groupChatEditTestsUserA from "@specs/reusable-accounts/ChatUserA/10-group-chat-edit-userA.spec"; +import groupChatSidebarTestsUserA from "@specs/reusable-accounts/ChatUserA/11-group-chats-sidebar-userA.spec"; describe("MacOS Chats Tests - User A", async () => { describe("Accept friend request and Chat", mainChatsTestsUserA.bind(this)); + describe("Chat Replies", repliesTestsUserA.bind(this)); + describe("Message Context Menu", messageContextMenuTestsUserA.bind(this)); + describe("Message Input", messageInputTestsUserA.bind(this)); + describe("Message Attachments", messageAttachmentsTestsUserA.bind(this)); + describe("Chat Topbar", chatTopbarTestsUserA.bind(this)); + describe("Quick Profile", quickProfileTestsUserA.bind(this)); + describe("Sidebar Chats", sidebarChatsTestsUserA.bind(this)); + describe("Group Chats Main", groupChatTestsUserA.bind(this)); + describe("Group Chats Edit", groupChatEditTestsUserA.bind(this)); + describe("Group Chats Sidebar", groupChatSidebarTestsUserA.bind(this)); }); diff --git a/tests/suites/Chats/03-ChatsUserB.suite.ts b/tests/suites/Chats/03-ChatsUserB.suite.ts index 07372222375..5b8b5e20b5e 100644 --- a/tests/suites/Chats/03-ChatsUserB.suite.ts +++ b/tests/suites/Chats/03-ChatsUserB.suite.ts @@ -1,6 +1,24 @@ import "module-alias/register"; import mainChatsTestsUserB from "@specs/reusable-accounts/ChatUserB/01-main-chats-userB.spec"; +import repliesTestsUserB from "@specs/reusable-accounts/ChatUserB/02-chat-replies-userB.spec"; +import messageContextMenuTestsUserB from "@specs/reusable-accounts/ChatUserB/03-message-context-menu-userB.spec"; +import messageInputTestsUserB from "@specs/reusable-accounts/ChatUserB/04-message-input-userB.spec"; +import messageAttachmentsTestsUserB from "@specs/reusable-accounts/ChatUserB/05-message-attachments-userB.spec"; +import quickProfileTestsUserB from "@specs/reusable-accounts/ChatUserB/06-quick-profile-userB.spec"; +import sidebarChatsTestsUserB from "@specs/reusable-accounts/ChatUserB/07-sidebar-chats-userB.spec"; +import groupChatTestsUserB from "@specs/reusable-accounts/ChatUserB/08-group-chats-userB.spec"; +import groupChatEditTestsUserB from "@specs/reusable-accounts/ChatUserB/09-group-chat-edit-userB.spec"; +import groupChatSidebarTestsUserB from "@specs/reusable-accounts/ChatUserB/10-group-chats-sidebar-userB.spec"; describe("MacOS Chats Tests - User B", async () => { describe("Send friend request and Chat", mainChatsTestsUserB.bind(this)); + describe("Chat Replies", repliesTestsUserB.bind(this)); + describe("Message Context Menu", messageContextMenuTestsUserB.bind(this)); + describe("Message Input", messageInputTestsUserB.bind(this)); + describe("Message Attachments", messageAttachmentsTestsUserB.bind(this)); + describe("Quick Profile", quickProfileTestsUserB.bind(this)); + describe("Sidebar Chats", sidebarChatsTestsUserB.bind(this)); + describe("Group Chats Main", groupChatTestsUserB.bind(this)); + describe("Group Chats Edit", groupChatEditTestsUserB.bind(this)); + describe("Group Chats Sidebar", groupChatSidebarTestsUserB.bind(this)); }); From 194eefdd7c45abfacb5117f05470e903e30e6926 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Carden=CC=83a?= <35935591+luisecm@users.noreply.github.com> Date: Mon, 6 Nov 2023 14:03:32 -0600 Subject: [PATCH 13/22] chore(appium): just attempt the first set of tests --- config/macos-chats/wdio.mac.chatA.conf.ts | 10 ++++ config/macos-chats/wdio.mac.chatB.conf.ts | 10 ++++ tests/screenobjects/friends/FriendsScreen.ts | 49 ++++++++++---------- tests/suites/Chats/02-ChatsUserA.suite.ts | 20 ++++---- tests/suites/Chats/03-ChatsUserB.suite.ts | 18 +++---- 5 files changed, 63 insertions(+), 44 deletions(-) diff --git a/config/macos-chats/wdio.mac.chatA.conf.ts b/config/macos-chats/wdio.mac.chatA.conf.ts index e55d3349852..46654d33e61 100644 --- a/config/macos-chats/wdio.mac.chatA.conf.ts +++ b/config/macos-chats/wdio.mac.chatA.conf.ts @@ -32,6 +32,16 @@ export const config: WebdriverIO.Config = { // 'path/to/excluded/files' ], specFileRetries: 0, + // Options to be passed to Mocha. + mochaOpts: { + ui: "bdd", + /** + * NOTE: This has been increased for more stable Appium Native app + * tests because they can take a bit longer. + */ + timeout: 300000, // 5min + bail: true, + }, // // ============ // Capabilities diff --git a/config/macos-chats/wdio.mac.chatB.conf.ts b/config/macos-chats/wdio.mac.chatB.conf.ts index 2b83c739ab5..a4c628fbc46 100644 --- a/config/macos-chats/wdio.mac.chatB.conf.ts +++ b/config/macos-chats/wdio.mac.chatB.conf.ts @@ -33,6 +33,16 @@ export const config: WebdriverIO.Config = { // 'path/to/excluded/files' ], specFileRetries: 0, + // Options to be passed to Mocha. + mochaOpts: { + ui: "bdd", + /** + * NOTE: This has been increased for more stable Appium Native app + * tests because they can take a bit longer. + */ + timeout: 300000, // 5min + bail: true, + }, // // ============ // Capabilities diff --git a/tests/screenobjects/friends/FriendsScreen.ts b/tests/screenobjects/friends/FriendsScreen.ts index 1a66f36321e..afbeafb3c8a 100644 --- a/tests/screenobjects/friends/FriendsScreen.ts +++ b/tests/screenobjects/friends/FriendsScreen.ts @@ -13,7 +13,7 @@ import { } from "@helpers/commands"; const currentOS = driver[USER_A_INSTANCE].capabilities.automationName; -const {keyboard, Key} = require("@nut-tree/nut-js"); +const { keyboard, Key } = require("@nut-tree/nut-js"); let SELECTORS = {}; @@ -368,7 +368,7 @@ export default class FriendsScreen extends UplinkMainScreen { async acceptIncomingRequest(name: string) { const friendToClick = await this.getExistingFriendByAriaLabel(name); const acceptButton = await friendToClick.$( - SELECTORS.ACCEPT_FRIEND_REQUEST_BUTTON + SELECTORS.ACCEPT_FRIEND_REQUEST_BUTTON, ); await acceptButton.click(); } @@ -578,7 +578,7 @@ export default class FriendsScreen extends UplinkMainScreen { async getUserImageProfile(username: string) { const userLocator = await this.getExistingFriendByAriaLabel(username); const userImageProfile = await userLocator.$( - SELECTORS.FRIEND_USER_IMAGE_PROFILE + SELECTORS.FRIEND_USER_IMAGE_PROFILE, ); await userImageProfile.waitForExist(); return userImageProfile; @@ -601,7 +601,7 @@ export default class FriendsScreen extends UplinkMainScreen { async getUserIndicatorOffline(username: string) { const userLocator = await this.getExistingFriendByAriaLabel(username); const indicatorOffline = await userLocator.$( - SELECTORS.FRIEND_USER_INDICATOR_OFFLINE + SELECTORS.FRIEND_USER_INDICATOR_OFFLINE, ); await indicatorOffline.waitForExist(); return indicatorOffline; @@ -617,10 +617,10 @@ export default class FriendsScreen extends UplinkMainScreen { timeout: 15000, timeoutMsg: "Expected indicator online was never displayed on Friends Screen User after 15 seconds", - } + }, ); const indicatorOnline = await userLocator.$( - SELECTORS.FRIEND_USER_INDICATOR_ONLINE + SELECTORS.FRIEND_USER_INDICATOR_ONLINE, ); return indicatorOnline; } @@ -664,7 +664,7 @@ export default class FriendsScreen extends UplinkMainScreen { async hoverOnBlockButton(username: string) { const userLocator = await this.getExistingFriendByAriaLabel(username); const secondButtonLocator = await userLocator.$( - SELECTORS.BLOCK_FRIEND_BUTTON + SELECTORS.BLOCK_FRIEND_BUTTON, ); await this.hoverOnElement(secondButtonLocator); } @@ -677,7 +677,7 @@ export default class FriendsScreen extends UplinkMainScreen { async hoverOnChatWithFriendButton(username: string) { const userLocator = await this.getExistingFriendByAriaLabel(username); const buttonLocator = await userLocator.$( - SELECTORS.CHAT_WITH_FRIEND_BUTTON + SELECTORS.CHAT_WITH_FRIEND_BUTTON, ); await this.hoverOnElement(buttonLocator); } @@ -690,7 +690,7 @@ export default class FriendsScreen extends UplinkMainScreen { async hoverOnUnfriendDenyUnblockButton(username: string) { const userLocator = await this.getExistingFriendByAriaLabel(username); const firstButtonLocator = await userLocator.$( - SELECTORS.REMOVE_OR_DENY_FRIEND_BUTTON + SELECTORS.REMOVE_OR_DENY_FRIEND_BUTTON, ); await this.hoverOnElement(firstButtonLocator); } @@ -714,7 +714,7 @@ export default class FriendsScreen extends UplinkMainScreen { async removeOrCancelUser(name: string) { const friendToClick = await this.getExistingFriendByAriaLabel(name); const removeOrDenyButton = await friendToClick.$( - SELECTORS.REMOVE_OR_DENY_FRIEND_BUTTON + SELECTORS.REMOVE_OR_DENY_FRIEND_BUTTON, ); await removeOrDenyButton.click(); } @@ -730,7 +730,7 @@ export default class FriendsScreen extends UplinkMainScreen { { timeout: 15000, timeoutMsg: "All friends list never shown any records after 15 seconds", - } + }, ); } @@ -751,7 +751,7 @@ export default class FriendsScreen extends UplinkMainScreen { timeout: 15000, timeoutMsg: "Blocked friends list never shown any records after 15 seconds", - } + }, ); } @@ -787,7 +787,7 @@ export default class FriendsScreen extends UplinkMainScreen { timeout: 15000, timeoutMsg: "Incoming friends list never shown any records after 15 seconds", - } + }, ); } @@ -819,7 +819,7 @@ export default class FriendsScreen extends UplinkMainScreen { timeout: 15000, timeoutMsg: "Expected friend list never shown any records after 15 seconds", - } + }, ); } @@ -835,11 +835,10 @@ export default class FriendsScreen extends UplinkMainScreen { async waitUntilFriendIsRemoved( username: string, - timeoutUser: number = 30000 + timeoutUser: number = 30000, ) { - const nonExistingFriend = await this.getNonExistingFriendByAriaLabel( - username - ); + const nonExistingFriend = + await this.getNonExistingFriendByAriaLabel(username); await this.instance .$(SELECTORS.FRIENDS_BODY) .$(nonExistingFriend) @@ -852,10 +851,10 @@ export default class FriendsScreen extends UplinkMainScreen { return await this.acceptFriendRequestButton; }, { - timeout: 15000, + timeout: 240000, timeoutMsg: - "Expected Accept Friend Request button was never displayed on Friends Screen after 15 seconds", - } + "Expected Accept Friend Request button was never displayed on Friends Screen after 4 minutes", + }, ); } @@ -865,10 +864,10 @@ export default class FriendsScreen extends UplinkMainScreen { return await this.chatWithFriendButton; }, { - timeout: 15000, + timeout: 240000, timeoutMsg: - "Expected Chat With Friend button was never displayed on Friends Screen after 15 seconds", - } + "Expected Chat With Friend button was never displayed on Friends Screen after 4 minutes", + }, ); } @@ -882,7 +881,7 @@ export default class FriendsScreen extends UplinkMainScreen { timeout: 15000, timeoutMsg: "Expected Username was never displayed on Friends Screen after 15 seconds", - } + }, ); } diff --git a/tests/suites/Chats/02-ChatsUserA.suite.ts b/tests/suites/Chats/02-ChatsUserA.suite.ts index b9694a554f1..a7d7703b708 100644 --- a/tests/suites/Chats/02-ChatsUserA.suite.ts +++ b/tests/suites/Chats/02-ChatsUserA.suite.ts @@ -13,14 +13,14 @@ import groupChatSidebarTestsUserA from "@specs/reusable-accounts/ChatUserA/11-gr describe("MacOS Chats Tests - User A", async () => { describe("Accept friend request and Chat", mainChatsTestsUserA.bind(this)); - describe("Chat Replies", repliesTestsUserA.bind(this)); - describe("Message Context Menu", messageContextMenuTestsUserA.bind(this)); - describe("Message Input", messageInputTestsUserA.bind(this)); - describe("Message Attachments", messageAttachmentsTestsUserA.bind(this)); - describe("Chat Topbar", chatTopbarTestsUserA.bind(this)); - describe("Quick Profile", quickProfileTestsUserA.bind(this)); - describe("Sidebar Chats", sidebarChatsTestsUserA.bind(this)); - describe("Group Chats Main", groupChatTestsUserA.bind(this)); - describe("Group Chats Edit", groupChatEditTestsUserA.bind(this)); - describe("Group Chats Sidebar", groupChatSidebarTestsUserA.bind(this)); + xdescribe("Chat Replies", repliesTestsUserA.bind(this)); + xdescribe("Message Context Menu", messageContextMenuTestsUserA.bind(this)); + xdescribe("Message Input", messageInputTestsUserA.bind(this)); + xdescribe("Message Attachments", messageAttachmentsTestsUserA.bind(this)); + xdescribe("Chat Topbar", chatTopbarTestsUserA.bind(this)); + xdescribe("Quick Profile", quickProfileTestsUserA.bind(this)); + xdescribe("Sidebar Chats", sidebarChatsTestsUserA.bind(this)); + xdescribe("Group Chats Main", groupChatTestsUserA.bind(this)); + xdescribe("Group Chats Edit", groupChatEditTestsUserA.bind(this)); + xdescribe("Group Chats Sidebar", groupChatSidebarTestsUserA.bind(this)); }); diff --git a/tests/suites/Chats/03-ChatsUserB.suite.ts b/tests/suites/Chats/03-ChatsUserB.suite.ts index 5b8b5e20b5e..2428d32ef23 100644 --- a/tests/suites/Chats/03-ChatsUserB.suite.ts +++ b/tests/suites/Chats/03-ChatsUserB.suite.ts @@ -12,13 +12,13 @@ import groupChatSidebarTestsUserB from "@specs/reusable-accounts/ChatUserB/10-gr describe("MacOS Chats Tests - User B", async () => { describe("Send friend request and Chat", mainChatsTestsUserB.bind(this)); - describe("Chat Replies", repliesTestsUserB.bind(this)); - describe("Message Context Menu", messageContextMenuTestsUserB.bind(this)); - describe("Message Input", messageInputTestsUserB.bind(this)); - describe("Message Attachments", messageAttachmentsTestsUserB.bind(this)); - describe("Quick Profile", quickProfileTestsUserB.bind(this)); - describe("Sidebar Chats", sidebarChatsTestsUserB.bind(this)); - describe("Group Chats Main", groupChatTestsUserB.bind(this)); - describe("Group Chats Edit", groupChatEditTestsUserB.bind(this)); - describe("Group Chats Sidebar", groupChatSidebarTestsUserB.bind(this)); + xdescribe("Chat Replies", repliesTestsUserB.bind(this)); + xdescribe("Message Context Menu", messageContextMenuTestsUserB.bind(this)); + xdescribe("Message Input", messageInputTestsUserB.bind(this)); + xdescribe("Message Attachments", messageAttachmentsTestsUserB.bind(this)); + xdescribe("Quick Profile", quickProfileTestsUserB.bind(this)); + xdescribe("Sidebar Chats", sidebarChatsTestsUserB.bind(this)); + xdescribe("Group Chats Main", groupChatTestsUserB.bind(this)); + xdescribe("Group Chats Edit", groupChatEditTestsUserB.bind(this)); + xdescribe("Group Chats Sidebar", groupChatSidebarTestsUserB.bind(this)); }); From 3505d1954527ddb517032667e2577f3ad6938cb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Carden=CC=83a?= <35935591+luisecm@users.noreply.github.com> Date: Mon, 6 Nov 2023 14:54:52 -0600 Subject: [PATCH 14/22] chore(appium): increase timeouts on remote wait methods --- .github/workflows/ui-automated-tests.yml | 25 +++---- tests/screenobjects/chats/ChatsLayout.ts | 2 +- tests/screenobjects/chats/ChatsSidebar.ts | 63 ++++++++-------- tests/screenobjects/chats/EditGroup.ts | 36 ++++----- tests/screenobjects/chats/FavoritesSidebar.ts | 37 +++++----- tests/screenobjects/chats/MessageGroup.ts | 36 ++++----- tests/screenobjects/chats/Messages.ts | 74 +++++++++---------- tests/screenobjects/chats/Topbar.ts | 20 ++--- tests/screenobjects/friends/FriendsScreen.ts | 37 +++++++--- .../ChatUserB/01-main-chats-userB.spec.ts | 2 +- 10 files changed, 170 insertions(+), 162 deletions(-) diff --git a/.github/workflows/ui-automated-tests.yml b/.github/workflows/ui-automated-tests.yml index e4910619231..f4c4b335be0 100644 --- a/.github/workflows/ui-automated-tests.yml +++ b/.github/workflows/ui-automated-tests.yml @@ -164,13 +164,13 @@ jobs: with: name: appium-log-macos path: ./appium.log - + - name: Run Tests on to Create First Account ๐Ÿงช run: npm run mac.createAccountA - + - name: Run Tests on to Create Second Account ๐Ÿงช run: npm run mac.createAccountB - + - name: Upload test accounts for Chat Users uses: actions/upload-artifact@v3 if: always() @@ -181,7 +181,7 @@ jobs: ./tests/fixtures/users/mac2/ChatUserB/ ./tests/fixtures/users/mac2/ChatUserA.json ./tests/fixtures/users/mac2/ChatUserB.json - + - name: Add label if any of test jobs failed if: failure() uses: buildsville/add-remove-label@v2.0.0 @@ -190,9 +190,11 @@ jobs: labels: | Failed Automated Test type: add - + test-mac-chats: strategy: + fail-fast: false + max-parallel: 2 matrix: job: ["chatA", "chatB"] include: @@ -212,13 +214,13 @@ jobs: with: name: Uplink-macos-latest path: ./apps - + - name: Download Test User Accounts ๐Ÿ—ณ๏ธ uses: actions/download-artifact@v3 with: name: appium-test-accounts path: ./tests/fixtures/users/mac2 - + - name: Enable opening app not codesigned ๐Ÿ–ฅ๏ธ run: sudo spctl --master-disable @@ -267,7 +269,7 @@ jobs: run: | rm -rf ~/.uplink cp -r ./tests/fixtures/users/mac2/${{ matrix.username }}/ ~/.uplink - + - name: Run Tests on MacOS ๐Ÿงช run: npm run mac.${{ matrix.job }} @@ -309,12 +311,7 @@ jobs: type: add remove-artifacts: - needs: - [ - build-mac, - test-mac, - test-mac-chats - ] + needs: [build-mac, test-mac, test-mac-chats] runs-on: ubuntu-latest steps: diff --git a/tests/screenobjects/chats/ChatsLayout.ts b/tests/screenobjects/chats/ChatsLayout.ts index 881a104a639..ad858ad9888 100644 --- a/tests/screenobjects/chats/ChatsLayout.ts +++ b/tests/screenobjects/chats/ChatsLayout.ts @@ -78,7 +78,7 @@ export default class ChatsLayout extends UplinkMainScreen { { timeout: 15000, timeoutMsg: "Expected chat layout was never displayed after 15 seconds", - } + }, ); } } diff --git a/tests/screenobjects/chats/ChatsSidebar.ts b/tests/screenobjects/chats/ChatsSidebar.ts index cee9c2e5818..0a93675dd00 100644 --- a/tests/screenobjects/chats/ChatsSidebar.ts +++ b/tests/screenobjects/chats/ChatsSidebar.ts @@ -326,17 +326,17 @@ export default class ChatsSidebar extends UplinkMainScreen { return (await sidebarStatusValue.getText()) === message; }, { - timeout: 15000, + timeout: 60000, timeoutMsg: - "Expected sidebar status value never include the message after 15 seconds", - } + "Expected sidebar status value never include the message after 60 seconds", + }, ); } async validateLastMessageTimeAgo() { const timeAgo = await this.sidebarChatsUserBadgeTimeAgoValue; await expect(timeAgo).toHaveTextContaining( - /(?:\d{1,2}\s+(?:second|minute)s?\s+ago|now)$/ + /(?:\d{1,2}\s+(?:second|minute)s?\s+ago|now)$/, ); } @@ -346,10 +346,10 @@ export default class ChatsSidebar extends UplinkMainScreen { return await this.sidebarChatsUserBadge.waitForExist({ reverse: true }); }, { - timeout: 15000, + timeout: 60000, timeoutMsg: - "Expected badge number of unread messages is still displayed after 15 seconds", - } + "Expected badge number of unread messages is still displayed after 60 seconds", + }, ); } @@ -361,9 +361,9 @@ export default class ChatsSidebar extends UplinkMainScreen { }); }, { - timeout: 15000, - timeoutMsg: "Sidebar chats are still displayed after 15 seconds", - } + timeout: 60000, + timeoutMsg: "Sidebar chats are still displayed after 60 seconds", + }, ); } @@ -377,9 +377,9 @@ export default class ChatsSidebar extends UplinkMainScreen { .waitForExist({ reverse: true }); }, { - timeout: 15000, - timeoutMsg: "Sidebar chats are still displayed after 15 seconds", - } + timeout: 60000, + timeoutMsg: "Sidebar chats are still displayed after 60 seconds", + }, ); } @@ -389,9 +389,9 @@ export default class ChatsSidebar extends UplinkMainScreen { return await this.sidebarGroupChatImage.waitForExist({ reverse: true }); }, { - timeout: 15000, - timeoutMsg: "Sidebar group chats are still displayed after 15 seconds", - } + timeout: 60000, + timeoutMsg: "Sidebar group chats are still displayed after 60 seconds", + }, ); } @@ -418,10 +418,10 @@ export default class ChatsSidebar extends UplinkMainScreen { return await this.sidebarChatsUserStatusValue; }, { - timeout: 15000, + timeout: 60000, timeoutMsg: - "Sidebar never displayed received messages after 15 seconds", - } + "Sidebar never displayed received messages after 60 seconds", + }, ); } @@ -459,10 +459,10 @@ export default class ChatsSidebar extends UplinkMainScreen { return await this.instance.$(SELECTORS.SIDEBAR).$(element); }, { - timeout: 15000, + timeout: 60000, timeoutMsg: - "Expected chat group was never displayed on Sidebar after 15 seconds", - } + "Expected chat group was never displayed on Sidebar after 60 seconds", + }, ); } @@ -476,16 +476,16 @@ export default class ChatsSidebar extends UplinkMainScreen { .waitForExist({ reverse: true }); }, { - timeout: 15000, - timeoutMsg: "Sidebar group was never deleted after 15 seconds", - } + timeout: 60000, + timeoutMsg: "Sidebar group was never deleted after 60 seconds", + }, ); } async getSidebarGroupPlusSome(groupname: string) { const groupLocator = await this.getExistingElementByAriaLabel(groupname); const plusSomeLocator = await groupLocator.$( - SELECTORS.SIDEBAR_GROUP_CHAT_PLUS_SOME + SELECTORS.SIDEBAR_GROUP_CHAT_PLUS_SOME, ); await plusSomeLocator.waitForExist(); return plusSomeLocator; @@ -551,10 +551,10 @@ export default class ChatsSidebar extends UplinkMainScreen { .$(SELECTORS.SIDEBAR_CHATS_USER_ONLINE_INDICATOR); }, { - timeout: 15000, + timeout: 60000, timeoutMsg: - "Expected indicator online was never displayed on Chats Sidebar after 15 seconds", - } + "Expected indicator online was never displayed on Chats Sidebar after 60 seconds", + }, ); const onlineLocator = await userLocator @@ -599,9 +599,8 @@ export default class ChatsSidebar extends UplinkMainScreen { } async openContextMenuOnGroupChat(groupName: string) { - const imageToRightClick = await this.getExistingElementByAriaLabel( - groupName - ); + const imageToRightClick = + await this.getExistingElementByAriaLabel(groupName); await this.hoverOnElement(imageToRightClick); const currentDriver = await this.getCurrentDriver(); if (currentDriver === macDriver) { diff --git a/tests/screenobjects/chats/EditGroup.ts b/tests/screenobjects/chats/EditGroup.ts index e2d43cf1a25..4ab5e7463f9 100644 --- a/tests/screenobjects/chats/EditGroup.ts +++ b/tests/screenobjects/chats/EditGroup.ts @@ -247,7 +247,7 @@ export default class EditGroup extends UplinkMainScreen { async clickOnFirstAddButton() { const firstAddButton = await this.instance.$$( - SELECTORS.ADD_PARTICIPANT_BUTTON + SELECTORS.ADD_PARTICIPANT_BUTTON, )[0]; await driver[this.executor].waitUntil( async () => { @@ -257,14 +257,14 @@ export default class EditGroup extends UplinkMainScreen { timeout: 15000, timeoutMsg: "Add friend button from Edit Group was never displayed after 15 seconds", - } + }, ); await firstAddButton.click(); } async clickOnFirstRemoveButton() { const removeParticipantButton = await this.instance.$$( - SELECTORS.REMOVE_PARTICIPANT_BUTTON + SELECTORS.REMOVE_PARTICIPANT_BUTTON, )[0]; await driver[this.executor].waitUntil( async () => { @@ -274,7 +274,7 @@ export default class EditGroup extends UplinkMainScreen { timeout: 15000, timeoutMsg: "Remove friend button from Edit Group was never displayed after 15 seconds", - } + }, ); await removeParticipantButton.click(); } @@ -314,7 +314,7 @@ export default class EditGroup extends UplinkMainScreen { .$( '//XCUIElementTypeGroup[@label="Friend Container"]/XCUIElementTypeGroup/XCUIElementTypeStaticText[contains(@value, "' + participant + - '")]/../..' + '")]/../..', ); } else if (currentDriver === WINDOWS_DRIVER) { locator = await this.instance @@ -322,7 +322,7 @@ export default class EditGroup extends UplinkMainScreen { .$( '//Group[@Name="Friend Container"]/Group/Text[contains(@Name, "' + participant + - '")]/../..' + '")]/../..', ); } return locator; @@ -338,7 +338,7 @@ export default class EditGroup extends UplinkMainScreen { async getParticipantIndicatorOffline(participant: string) { const userLocator = await this.getParticipantContainerLocator(participant); const indicatorOffline = await userLocator.$( - SELECTORS.PARTICIPANT_USER_INDICATOR_OFFLINE + SELECTORS.PARTICIPANT_USER_INDICATOR_OFFLINE, ); await indicatorOffline.waitForExist(); return indicatorOffline; @@ -351,14 +351,14 @@ export default class EditGroup extends UplinkMainScreen { return await userLocator.$(SELECTORS.PARTICIPANT_USER_INDICATOR_ONLINE); }, { - timeout: 15000, + timeout: 60000, timeoutMsg: - "Expected indicator online was never displayed on Edit Group Users List after 15 seconds", - } + "Expected indicator online was never displayed on Edit Group Users List after 60 seconds", + }, ); const indicatorOnline = await userLocator.$( - SELECTORS.PARTICIPANT_USER_INDICATOR_ONLINE + SELECTORS.PARTICIPANT_USER_INDICATOR_ONLINE, ); return indicatorOnline; } @@ -366,7 +366,7 @@ export default class EditGroup extends UplinkMainScreen { async getParticipantUserCreatorBadgeImage(participant: string) { const userLocator = await this.getParticipantContainerLocator(participant); const badgeImage = await userLocator.$( - SELECTORS.PARTICIPANT_USER_CREATOR_BADGE_IMAGE + SELECTORS.PARTICIPANT_USER_CREATOR_BADGE_IMAGE, ); await badgeImage.waitForExist(); return badgeImage; @@ -375,7 +375,7 @@ export default class EditGroup extends UplinkMainScreen { async getParticipantUserCreatorBadgeText(participant: string) { const userLocator = await this.getParticipantContainerLocator(participant); const badgeText = await userLocator.$( - SELECTORS.PARTICIPANT_USER_CREATOR_BADGE_TEXT + SELECTORS.PARTICIPANT_USER_CREATOR_BADGE_TEXT, ); await badgeText.waitForExist(); return badgeText; @@ -391,7 +391,7 @@ export default class EditGroup extends UplinkMainScreen { async getParticipantUserImageProfile(participant: string) { const userLocator = await this.getParticipantContainerLocator(participant); const userImageProfile = await userLocator.$( - SELECTORS.PARTICIPANT_USER_IMAGE_PROFILE + SELECTORS.PARTICIPANT_USER_IMAGE_PROFILE, ); await userImageProfile.waitForExist(); return userImageProfile; @@ -400,7 +400,7 @@ export default class EditGroup extends UplinkMainScreen { async getParticipantUserImageWrap(participant: string) { const userLocator = await this.getParticipantContainerLocator(participant); const userImageWrap = await userLocator.$( - SELECTORS.PARTICIPANT_USER_IMAGE_WRAP + SELECTORS.PARTICIPANT_USER_IMAGE_WRAP, ); await userImageWrap.waitForExist(); return userImageWrap; @@ -443,9 +443,9 @@ export default class EditGroup extends UplinkMainScreen { return await this.getParticipantIndicatorOnline(username); }, { - timeout: 15000, - timeoutMsg: "Expected chat layout was never displayed after 15 seconds", - } + timeout: 60000, + timeoutMsg: "Expected chat layout was never displayed after 60 seconds", + }, ); } } diff --git a/tests/screenobjects/chats/FavoritesSidebar.ts b/tests/screenobjects/chats/FavoritesSidebar.ts index cca99435ed4..12d497f8456 100644 --- a/tests/screenobjects/chats/FavoritesSidebar.ts +++ b/tests/screenobjects/chats/FavoritesSidebar.ts @@ -191,7 +191,7 @@ export default class FavoritesSidebar extends UplinkMainScreen { timeout: 15000, timeoutMsg: "Expected Favorite User was never displayed after 15 seconds", - } + }, ); const favoritesElement = await this.instance .$(SELECTORS.SLIMBAR) @@ -209,7 +209,7 @@ export default class FavoritesSidebar extends UplinkMainScreen { timeout: 15000, timeoutMsg: "Expected user image was never displayed on Favorites Sidebar after 15 seconds", - } + }, ); const userImage = await favoriteLocator.$(SELECTORS.FAVORITES_USER_IMAGE); return userImage; @@ -220,18 +220,18 @@ export default class FavoritesSidebar extends UplinkMainScreen { await driver[this.executor].waitUntil( async () => { return await favoriteLocator.$( - SELECTORS.FAVORITES_USER_IMAGE_GROUP_WRAP + SELECTORS.FAVORITES_USER_IMAGE_GROUP_WRAP, ); }, { timeout: 15000, timeoutMsg: "Expected user image group wrap was never displayed on Favorites Sidebar after 15 seconds", - } + }, ); const userImageGroupWrap = await favoriteLocator.$( - SELECTORS.FAVORITES_USER_IMAGE_GROUP_WRAP + SELECTORS.FAVORITES_USER_IMAGE_GROUP_WRAP, ); return userImageGroupWrap; } @@ -239,7 +239,7 @@ export default class FavoritesSidebar extends UplinkMainScreen { async getFavoritesUserImageProfile(username: string) { const favoriteLocator = await this.getFavoritesUserByAriaLabel(username); const imageProfile = await favoriteLocator.$( - SELECTORS.FAVORITES_USER_IMAGE_PROFILE + SELECTORS.FAVORITES_USER_IMAGE_PROFILE, ); await imageProfile.waitForExist(); return imageProfile; @@ -248,7 +248,7 @@ export default class FavoritesSidebar extends UplinkMainScreen { async getFavoritesUserImageWrap(username: string) { const favoriteLocator = await this.getFavoritesUserByAriaLabel(username); const userImageWrap = await favoriteLocator.$( - SELECTORS.FAVORITES_USER_IMAGE_WRAP + SELECTORS.FAVORITES_USER_IMAGE_WRAP, ); await userImageWrap.waitForExist(); return userImageWrap; @@ -257,7 +257,7 @@ export default class FavoritesSidebar extends UplinkMainScreen { async getFavoritesUserIndicator(username: string) { const favoriteLocator = await this.getFavoritesUserByAriaLabel(username); const indicator = await favoriteLocator.$( - SELECTORS.FAVORITES_USER_INDICATOR + SELECTORS.FAVORITES_USER_INDICATOR, ); await indicator.waitForExist(); return indicator; @@ -266,7 +266,7 @@ export default class FavoritesSidebar extends UplinkMainScreen { async getFavoritesUserIndicatorOffline(username: string) { const favoriteLocator = await this.getFavoritesUserByAriaLabel(username); const indicatorOffline = await favoriteLocator.$( - SELECTORS.FAVORITES_USER_INDICATOR_OFFLINE + SELECTORS.FAVORITES_USER_INDICATOR_OFFLINE, ); await indicatorOffline.waitForExist(); return indicatorOffline; @@ -277,18 +277,18 @@ export default class FavoritesSidebar extends UplinkMainScreen { await driver[this.executor].waitUntil( async () => { return await favoriteLocator.$( - SELECTORS.FAVORITES_USER_INDICATOR_ONLINE + SELECTORS.FAVORITES_USER_INDICATOR_ONLINE, ); }, { - timeout: 15000, + timeout: 60000, timeoutMsg: - "Expected indicator online was never displayed on Favorite User after 15 seconds", - } + "Expected indicator online was never displayed on Favorite User after 60 seconds", + }, ); const indicatorOnline = await favoriteLocator.$( - SELECTORS.FAVORITES_USER_INDICATOR_ONLINE + SELECTORS.FAVORITES_USER_INDICATOR_ONLINE, ); return indicatorOnline; } @@ -314,7 +314,7 @@ export default class FavoritesSidebar extends UplinkMainScreen { timeout: 15000, timeoutMsg: "Expected Context Menu was never displayed after 15 seconds", - } + }, ); } @@ -370,7 +370,7 @@ export default class FavoritesSidebar extends UplinkMainScreen { { timeout: 15000, timeoutMsg: "Expected Favorites were never displayed after 15 seconds", - } + }, ); } @@ -380,9 +380,8 @@ export default class FavoritesSidebar extends UplinkMainScreen { } async validateFavoritesIndicatorOnline(username: string) { - const indicatorOnline = await this.getFavoritesUserIndicatorOnline( - username - ); + const indicatorOnline = + await this.getFavoritesUserIndicatorOnline(username); await indicatorOnline.waitForDisplayed(); } } diff --git a/tests/screenobjects/chats/MessageGroup.ts b/tests/screenobjects/chats/MessageGroup.ts index 9dff4a914e7..f40295e162d 100644 --- a/tests/screenobjects/chats/MessageGroup.ts +++ b/tests/screenobjects/chats/MessageGroup.ts @@ -78,7 +78,7 @@ export default class MessageGroup extends UplinkMainScreen { constructor(executor: string) { super( executor, - SELECTORS.MESSAGE_GROUP_WRAP_REMOTE || SELECTORS.MESSAGE_GROUP_WRAP_SENT + SELECTORS.MESSAGE_GROUP_WRAP_REMOTE || SELECTORS.MESSAGE_GROUP_WRAP_SENT, ); } @@ -247,7 +247,7 @@ export default class MessageGroup extends UplinkMainScreen { async getLastGroupWrapReceivedOnline() { const groupWrap = await this.getLastGroupWrapReceived(); const onlineStatus = await groupWrap.$( - SELECTORS.MESSAGE_GROUP_USER_INDICATOR_ONLINE + SELECTORS.MESSAGE_GROUP_USER_INDICATOR_ONLINE, ); await onlineStatus.waitForExist(); return onlineStatus; @@ -281,7 +281,7 @@ export default class MessageGroup extends UplinkMainScreen { async getLastGroupWrapSentOnline() { const groupWrap = await this.getLastGroupWrapSent(); const onlineStatus = await groupWrap.$( - SELECTORS.MESSAGE_GROUP_USER_INDICATOR_ONLINE + SELECTORS.MESSAGE_GROUP_USER_INDICATOR_ONLINE, ); await onlineStatus.waitForExist(); return onlineStatus; @@ -306,7 +306,7 @@ export default class MessageGroup extends UplinkMainScreen { timeout: 15000, timeoutMsg: "Expected pin indicator was never added to received message after 15 seconds", - } + }, ); const pinIndicator = await lastGroupReceived.$(SELECTORS.PIN_INDICATOR); @@ -340,7 +340,7 @@ export default class MessageGroup extends UplinkMainScreen { timeout: 15000, timeoutMsg: "Expected pin indicator was never added to sent message after 15 seconds", - } + }, ); const pinIndicator = await lastGroupSent.$(SELECTORS.PIN_INDICATOR); @@ -375,7 +375,7 @@ export default class MessageGroup extends UplinkMainScreen { async getLastMessageReceivedReactionsContainer() { const lastGroupReceived = await this.getLastReceivedGroup(); const reactionContainers = await lastGroupReceived.$$( - SELECTORS.MESSAGE_REACTION_CONTAINER + SELECTORS.MESSAGE_REACTION_CONTAINER, ); const lastContainerIndex = (await reactionContainers.length) - 1; const lastContainerLocator = await reactionContainers[lastContainerIndex]; @@ -386,7 +386,7 @@ export default class MessageGroup extends UplinkMainScreen { const reactionsContainer = await this.getLastMessageReceivedReactionsContainer(); const remoteReactions = await reactionsContainer.$$( - SELECTORS.EMOJI_REACTION_REMOTE + SELECTORS.EMOJI_REACTION_REMOTE, ); let results = []; for (let reaction of remoteReactions) { @@ -401,7 +401,7 @@ export default class MessageGroup extends UplinkMainScreen { const reactionsContainer = await this.getLastMessageReceivedReactionsContainer(); const selfReactions = await reactionsContainer.$$( - SELECTORS.EMOJI_REACTION_SELF + SELECTORS.EMOJI_REACTION_SELF, ); let results = []; for (let reaction of selfReactions) { @@ -415,7 +415,7 @@ export default class MessageGroup extends UplinkMainScreen { async getLastMessageSentReactionsContainer() { const lastGroupSent = await this.getLastSentGroup(); const reactionContainers = await lastGroupSent.$$( - SELECTORS.MESSAGE_REACTION_CONTAINER + SELECTORS.MESSAGE_REACTION_CONTAINER, ); const lastContainerIndex = (await reactionContainers.length) - 1; const lastContainerLocator = await reactionContainers[lastContainerIndex]; @@ -426,7 +426,7 @@ export default class MessageGroup extends UplinkMainScreen { const reactionsContainer = await this.getLastMessageSentReactionsContainer(); const remoteReactions = await reactionsContainer.$$( - SELECTORS.EMOJI_REACTION_REMOTE + SELECTORS.EMOJI_REACTION_REMOTE, ); let results = []; for (let reaction of remoteReactions) { @@ -441,7 +441,7 @@ export default class MessageGroup extends UplinkMainScreen { const reactionsContainer = await this.getLastMessageSentReactionsContainer(); const selfReactions = await reactionsContainer.$$( - SELECTORS.EMOJI_REACTION_SELF + SELECTORS.EMOJI_REACTION_SELF, ); let results = []; for (let reaction of selfReactions) { @@ -471,10 +471,10 @@ export default class MessageGroup extends UplinkMainScreen { return await this.instance.$(emojiReactionLocator); }, { - timeout: 15000, + timeout: 60000, timeoutMsg: - "Expected remote emoji reaction is still not displayed after 15 seconds", - } + "Expected remote emoji reaction is still not displayed after 60 seconds", + }, ); } @@ -500,7 +500,7 @@ export default class MessageGroup extends UplinkMainScreen { timeout: 15000, timeoutMsg: "Expected self emoji reaction is still not displayed after 15 seconds", - } + }, ); } @@ -509,7 +509,7 @@ export default class MessageGroup extends UplinkMainScreen { async getFirstMessageInLastGroupReceived() { const lastGroupSent = await this.getLastReceivedGroup(); const firstMessage = await lastGroupSent.$( - SELECTORS.CHAT_MESSAGE_LOCAL_FIRST + SELECTORS.CHAT_MESSAGE_LOCAL_FIRST, ); return firstMessage; } @@ -517,7 +517,7 @@ export default class MessageGroup extends UplinkMainScreen { async getLastMessageInLastGroupReceived() { const lastGroupSent = await this.getLastReceivedGroup(); const lastMessage = await lastGroupSent.$( - SELECTORS.CHAT_MESSAGE_LOCAL_LAST + SELECTORS.CHAT_MESSAGE_LOCAL_LAST, ); return lastMessage; } @@ -525,7 +525,7 @@ export default class MessageGroup extends UplinkMainScreen { async getMiddleMessageInLastGroupReceived(index: number) { const lastGroupSent = await this.getLastReceivedGroup(); const middleMessage = await lastGroupSent.$$( - SELECTORS.CHAT_MESSAGE_LOCAL_MIDDLE + SELECTORS.CHAT_MESSAGE_LOCAL_MIDDLE, )[index]; return middleMessage; } diff --git a/tests/screenobjects/chats/Messages.ts b/tests/screenobjects/chats/Messages.ts index 1445bc474d2..649a8fd3c1e 100644 --- a/tests/screenobjects/chats/Messages.ts +++ b/tests/screenobjects/chats/Messages.ts @@ -95,7 +95,7 @@ export default class Messages extends UplinkMainScreen { constructor(executor: string) { super( executor, - SELECTORS.CHAT_MESSAGE_LOCAL || SELECTORS.CHAT_MESSAGE_REMOTE + SELECTORS.CHAT_MESSAGE_LOCAL || SELECTORS.CHAT_MESSAGE_REMOTE, ); } @@ -309,7 +309,7 @@ export default class Messages extends UplinkMainScreen { const message = await this.getLastMessageReceivedLocator(); const messageText = await message.$(SELECTORS.CHAT_MESSAGE_TEXT_GROUP); const messageCodeLanguage = await messageText.$( - SELECTORS.CHAT_MESSAGE_CODE_LANGUAGE + SELECTORS.CHAT_MESSAGE_CODE_LANGUAGE, ); return messageCodeLanguage; } @@ -327,7 +327,7 @@ export default class Messages extends UplinkMainScreen { const messageCodePane = await this.getLastMessageReceivedCodePane(); let messageResult = ""; const messageResultElements = await messageCodePane.$$( - SELECTORS.CHAT_MESSAGE_CODE_MESSAGES + SELECTORS.CHAT_MESSAGE_CODE_MESSAGES, ); for (let element of messageResultElements) { const codeMessageText = await element.getText(); @@ -355,9 +355,9 @@ export default class Messages extends UplinkMainScreen { return await this.instance.$(locator); }, { - timeout: 15000, - timeoutMsg: "Expected message was never received after 15 seconds", - } + timeout: 60000, + timeoutMsg: "Expected message was never received after 60 seconds", + }, ); const element = await this.instance.$(locator); return element; @@ -396,7 +396,7 @@ export default class Messages extends UplinkMainScreen { async waitForCodeMessageSentToExist( expectedLanguage: string, - timeoutMsg: number = 30000 + timeoutMsg: number = 30000, ) { const currentDriver = await this.getCurrentDriver(); let codeMessageLocator: string = ""; @@ -418,7 +418,7 @@ export default class Messages extends UplinkMainScreen { { timeout: 15000, timeoutMsg: "Expected code message was never sent after 15 seconds", - } + }, ); } @@ -431,7 +431,7 @@ export default class Messages extends UplinkMainScreen { .$( '//XCUIElementTypeGroup[@label="message-text"]//XCUIElementTypeStaticText[contains(@value, "' + expectedMessage + - '")]' + '")]', ) .waitForExist({ reverse: true }); } else if (currentDriver === WINDOWS_DRIVER) { @@ -439,7 +439,7 @@ export default class Messages extends UplinkMainScreen { .$( '//Group[@Name="message-text"]//Text[contains(@Name, "' + expectedMessage + - '")]' + '")]', ) .waitForExist({ reverse: true }); } @@ -447,7 +447,7 @@ export default class Messages extends UplinkMainScreen { { timeout: 15000, timeoutMsg: "Expected message was not deleted after 15 seconds", - } + }, ); } @@ -473,7 +473,7 @@ export default class Messages extends UplinkMainScreen { timeout: 15000, timeoutMsg: "Expected chat message with link was not sent after 15 seconds", - } + }, ); } @@ -498,7 +498,7 @@ export default class Messages extends UplinkMainScreen { { timeout: 15000, timeoutMsg: "Expected chat message was not sent after 15 seconds", - } + }, ); } @@ -522,9 +522,9 @@ export default class Messages extends UplinkMainScreen { return await this.instance.$(codeMessageReceivedLocator); }, { - timeout: 15000, - timeoutMsg: "Expected code message was not received after 15 seconds", - } + timeout: 60000, + timeoutMsg: "Expected code message was not received after 60 seconds", + }, ); } @@ -548,9 +548,9 @@ export default class Messages extends UplinkMainScreen { return await this.instance.$(linkReceivedLocator); }, { - timeout: 15000, - timeoutMsg: "Expected link message was not received after 15 seconds", - } + timeout: 60000, + timeoutMsg: "Expected link message was not received after 60 seconds", + }, ); } @@ -574,9 +574,9 @@ export default class Messages extends UplinkMainScreen { return await this.instance.$(receivedMessageLocator); }, { - timeout: 15000, - timeoutMsg: "Expected chat message was not received after 15 seconds", - } + timeout: 60000, + timeoutMsg: "Expected chat message was not received after 60 seconds", + }, ); } @@ -601,7 +601,7 @@ export default class Messages extends UplinkMainScreen { const message = await this.getLastMessageSentLocator(); const messageText = await message.$(SELECTORS.CHAT_MESSAGE_TEXT_GROUP); const messageCodeLanguage = await messageText.$( - SELECTORS.CHAT_MESSAGE_CODE_LANGUAGE + SELECTORS.CHAT_MESSAGE_CODE_LANGUAGE, ); await messageCodeLanguage.waitForExist(); return messageCodeLanguage; @@ -620,7 +620,7 @@ export default class Messages extends UplinkMainScreen { const messageCodePane = await this.getLastMessageSentCodePane(); let messageResult = ""; const messageResultElements = await messageCodePane.$$( - SELECTORS.CHAT_MESSAGE_CODE_MESSAGES + SELECTORS.CHAT_MESSAGE_CODE_MESSAGES, ); for (let element of messageResultElements) { const codeMessageText = await element.getText(); @@ -651,7 +651,7 @@ export default class Messages extends UplinkMainScreen { { timeout: 15000, timeoutMsg: "Expected chat message was not sent after 15 seconds", - } + }, ); } @@ -766,7 +766,7 @@ export default class Messages extends UplinkMainScreen { async getLastMessageReceivedDownloadButton() { const lastMessage = await this.getLastMessageReceivedLocator(); const getLastMessageDownloadButton = await lastMessage.$( - SELECTORS.CHAT_MESSAGE_FILE_BUTTON + SELECTORS.CHAT_MESSAGE_FILE_BUTTON, ); await getLastMessageDownloadButton.waitForExist(); return getLastMessageDownloadButton; @@ -775,7 +775,7 @@ export default class Messages extends UplinkMainScreen { async getLastMessageReceivedFileEmbed() { const lastMessage = await this.getLastMessageReceivedLocator(); const lastMessageFileEmbed = await lastMessage.$( - SELECTORS.CHAT_MESSAGE_FILE_EMBED_REMOTE + SELECTORS.CHAT_MESSAGE_FILE_EMBED_REMOTE, ); await lastMessageFileEmbed.waitForExist(); return lastMessageFileEmbed; @@ -784,7 +784,7 @@ export default class Messages extends UplinkMainScreen { async getLastMessageReceivedFileIcon() { const lastMessage = await this.getLastMessageReceivedLocator(); const lastMessageFileIcon = await lastMessage.$( - SELECTORS.CHAT_MESSAGE_FILE_ICON + SELECTORS.CHAT_MESSAGE_FILE_ICON, ); await lastMessageFileIcon.waitForExist(); return lastMessageFileIcon; @@ -811,7 +811,7 @@ export default class Messages extends UplinkMainScreen { async getLastMessageSentDownloadButton() { const lastMessage = await this.getLastMessageSentLocator(); const getLastMessageSentDownloadButton = await lastMessage.$( - SELECTORS.CHAT_MESSAGE_FILE_BUTTON + SELECTORS.CHAT_MESSAGE_FILE_BUTTON, ); await getLastMessageSentDownloadButton.waitForExist(); return getLastMessageSentDownloadButton; @@ -820,7 +820,7 @@ export default class Messages extends UplinkMainScreen { async getLastMessageSentFileEmbed() { const lastMessage = await this.getLastMessageSentLocator(); const lastMessageFileEmbed = await lastMessage.$( - SELECTORS.CHAT_MESSAGE_FILE_EMBED + SELECTORS.CHAT_MESSAGE_FILE_EMBED, ); await lastMessageFileEmbed.waitForExist(); return lastMessageFileEmbed; @@ -829,7 +829,7 @@ export default class Messages extends UplinkMainScreen { async getLastMessageSentFileIcon() { const lastMessage = await this.getLastMessageSentLocator(); const lastMessageFileIcon = await lastMessage.$( - SELECTORS.CHAT_MESSAGE_FILE_ICON + SELECTORS.CHAT_MESSAGE_FILE_ICON, ); await lastMessageFileIcon.waitForExist(); return lastMessageFileIcon; @@ -857,7 +857,7 @@ export default class Messages extends UplinkMainScreen { async getLastMessageReceivedLinkEmbed() { const lastMessage = await this.getLastMessageReceivedLocator(); const lastMessageLinkEmbed = await lastMessage.$( - SELECTORS.CHAT_MESSAGE_LINK_EMBED + SELECTORS.CHAT_MESSAGE_LINK_EMBED, ); await lastMessageLinkEmbed.waitForExist({ timeout: 30000 }); return lastMessageLinkEmbed; @@ -875,7 +875,7 @@ export default class Messages extends UplinkMainScreen { async getLastMessageReceivedLinkEmbedIcon() { const linkEmbedLastMessage = await this.getLastMessageReceivedLinkEmbed(); const linkEmbedIcon = await linkEmbedLastMessage.$( - SELECTORS.CHAT_MESSAGE_LINK_EMBED_ICON + SELECTORS.CHAT_MESSAGE_LINK_EMBED_ICON, ); await linkEmbedIcon.waitForExist(); return linkEmbedIcon; @@ -885,7 +885,7 @@ export default class Messages extends UplinkMainScreen { const linkEmbedIconLastMessage = await this.getLastMessageReceivedLinkEmbedIcon(); const iconTitle = await linkEmbedIconLastMessage.$( - SELECTORS.CHAT_MESSAGE_LINK_EMBED_TITLE + SELECTORS.CHAT_MESSAGE_LINK_EMBED_TITLE, ); await iconTitle.waitForExist(); return iconTitle; @@ -894,7 +894,7 @@ export default class Messages extends UplinkMainScreen { async getLastMessageSentLinkEmbed() { const lastMessage = await this.getLastMessageSentLocator(); const lastMessageLinkEmbed = await lastMessage.$( - SELECTORS.CHAT_MESSAGE_LINK_EMBED + SELECTORS.CHAT_MESSAGE_LINK_EMBED, ); await lastMessageLinkEmbed.waitForExist({ timeout: 30000 }); return lastMessageLinkEmbed; @@ -912,7 +912,7 @@ export default class Messages extends UplinkMainScreen { async getLastMessageSentLinkEmbedIcon() { const linkEmbedLastMessage = await this.getLastMessageSentLinkEmbed(); const linkEmbedIcon = await linkEmbedLastMessage.$( - SELECTORS.CHAT_MESSAGE_LINK_EMBED_ICON + SELECTORS.CHAT_MESSAGE_LINK_EMBED_ICON, ); await linkEmbedIcon.waitForExist(); return linkEmbedIcon; @@ -922,7 +922,7 @@ export default class Messages extends UplinkMainScreen { const linkEmbedIconLastMessage = await this.getLastMessageSentLinkEmbedIcon(); const iconTitle = await linkEmbedIconLastMessage.$( - SELECTORS.CHAT_MESSAGE_LINK_EMBED_TITLE + SELECTORS.CHAT_MESSAGE_LINK_EMBED_TITLE, ); await iconTitle.waitForExist(); return iconTitle; diff --git a/tests/screenobjects/chats/Topbar.ts b/tests/screenobjects/chats/Topbar.ts index 7599e9049b3..9b3cc74d6fc 100644 --- a/tests/screenobjects/chats/Topbar.ts +++ b/tests/screenobjects/chats/Topbar.ts @@ -235,7 +235,7 @@ export default class Topbar extends UplinkMainScreen { timeout: 15000, timeoutMsg: "Remove from favorites button was not displayed after passing 15 seconds from adding the same user of favorites", - } + }, ); } @@ -298,10 +298,10 @@ export default class Topbar extends UplinkMainScreen { return await this.topbarIndicatorOnline; }, { - timeout: 15000, + timeout: 60000, timeoutMsg: - "Expected indicator online was never displayed on Chat Screen topbar after 15 seconds", - } + "Expected indicator online was never displayed on Chat Screen topbar after 60 seconds", + }, ); } @@ -314,7 +314,7 @@ export default class Topbar extends UplinkMainScreen { timeout: 15000, timeoutMsg: "Expected username was never displayed on Chat Screen topbar after 15 seconds", - } + }, ); } @@ -327,7 +327,7 @@ export default class Topbar extends UplinkMainScreen { timeout: 15000, timeoutMsg: "Expected user image was never displayed on Chat Screen topbar after 15 seconds", - } + }, ); } @@ -339,7 +339,7 @@ export default class Topbar extends UplinkMainScreen { { timeout: 15000, timeoutMsg: "Chats Topbar was never shown after 15 seconds", - } + }, ); } @@ -349,9 +349,9 @@ export default class Topbar extends UplinkMainScreen { return await this.topbarIndicatorOnline; }, { - timeout: 15000, - timeoutMsg: "Remote user never shown as online after 15 seconds", - } + timeout: 60000, + timeoutMsg: "Remote user never shown as online after 60 seconds", + }, ); } } diff --git a/tests/screenobjects/friends/FriendsScreen.ts b/tests/screenobjects/friends/FriendsScreen.ts index afbeafb3c8a..96a3815afbc 100644 --- a/tests/screenobjects/friends/FriendsScreen.ts +++ b/tests/screenobjects/friends/FriendsScreen.ts @@ -614,9 +614,9 @@ export default class FriendsScreen extends UplinkMainScreen { return await userLocator.$(SELECTORS.FRIEND_USER_INDICATOR_ONLINE); }, { - timeout: 15000, + timeout: 60000, timeoutMsg: - "Expected indicator online was never displayed on Friends Screen User after 15 seconds", + "Expected indicator online was never displayed on Friends Screen User after 60 seconds", }, ); const indicatorOnline = await userLocator.$( @@ -728,8 +728,8 @@ export default class FriendsScreen extends UplinkMainScreen { .$(SELECTORS.FRIEND_INFO_USERNAME); }, { - timeout: 15000, - timeoutMsg: "All friends list never shown any records after 15 seconds", + timeout: 60000, + timeoutMsg: "All friends list never shown any records after 60 seconds", }, ); } @@ -748,9 +748,9 @@ export default class FriendsScreen extends UplinkMainScreen { .$(SELECTORS.FRIEND_INFO_USERNAME); }, { - timeout: 15000, + timeout: 60000, timeoutMsg: - "Blocked friends list never shown any records after 15 seconds", + "Blocked friends list never shown any records after 60 seconds", }, ); } @@ -765,6 +765,19 @@ export default class FriendsScreen extends UplinkMainScreen { await chatWithFriend.waitForExist(); } + async validateChatWithFriendButtonExists() { + // Wait until incoming list is not empty + await driver[this.executor].waitUntil( + async () => { + return await this.chatWithFriendButton; + }, + { + timeout: 60000, + timeoutMsg: "Chat with friend button does not exist after 60 seconds", + }, + ); + } + async validateFriendsButtonBadgeIsShown() { const friendsButtonBadge = await this.friendsButtonBadge; await friendsButtonBadge.waitForExist(); @@ -784,9 +797,9 @@ export default class FriendsScreen extends UplinkMainScreen { .$(SELECTORS.FRIEND_INFO_USERNAME); }, { - timeout: 15000, + timeout: 60000, timeoutMsg: - "Incoming friends list never shown any records after 15 seconds", + "Incoming friends list never shown any records after 60 seconds", }, ); } @@ -816,9 +829,9 @@ export default class FriendsScreen extends UplinkMainScreen { .$(SELECTORS.FRIEND_INFO_USERNAME); }, { - timeout: 15000, + timeout: 60000, timeoutMsg: - "Expected friend list never shown any records after 15 seconds", + "Expected friend list never shown any records after 60 seconds", }, ); } @@ -878,9 +891,9 @@ export default class FriendsScreen extends UplinkMainScreen { return await user.$(SELECTORS.FRIEND_INFO_USERNAME); }, { - timeout: 15000, + timeout: 60000, timeoutMsg: - "Expected Username was never displayed on Friends Screen after 15 seconds", + "Expected Username was never displayed on Friends Screen after 60 seconds", }, ); } diff --git a/tests/specs/reusable-accounts/ChatUserB/01-main-chats-userB.spec.ts b/tests/specs/reusable-accounts/ChatUserB/01-main-chats-userB.spec.ts index 6643b0d187e..42dffed183a 100644 --- a/tests/specs/reusable-accounts/ChatUserB/01-main-chats-userB.spec.ts +++ b/tests/specs/reusable-accounts/ChatUserB/01-main-chats-userB.spec.ts @@ -52,7 +52,7 @@ export default async function mainChatsTestsUserB() { it("Chat User B - Wait until the other user is connected", async () => { // Go to the current list of All friends and then open a Chat conversation with ChatUserA - await friendsScreenFirstUser.chatWithFriendButton.waitForExist(); + await friendsScreenFirstUser.validateChatWithFriendButtonExists(); await friendsScreenFirstUser.hoverOnChatWithFriendButton("ChatUserA"); await friendsScreenFirstUser.chatWithFriendButton.click(); await chatsTopbarFirstUser.validateTopbarExists(); From 9a55fa19214b374a9c3cd690a53ca542719fc85c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Carden=CC=83a?= <35935591+luisecm@users.noreply.github.com> Date: Mon, 6 Nov 2023 17:32:32 -0600 Subject: [PATCH 15/22] test(update): adjust chats tests to two GH runners --- tests/screenobjects/chats/ChatsLayout.ts | 3 +-- .../ChatUserB/01-main-chats-userB.spec.ts | 7 +------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/tests/screenobjects/chats/ChatsLayout.ts b/tests/screenobjects/chats/ChatsLayout.ts index ad858ad9888..6e405f6753c 100644 --- a/tests/screenobjects/chats/ChatsLayout.ts +++ b/tests/screenobjects/chats/ChatsLayout.ts @@ -22,8 +22,7 @@ const SELECTORS_WINDOWS = { const SELECTORS_MACOS = { ENCRYPTED_MESSAGES: "~messages-secured-alert", - ENCRYPTED_MESSAGES_TEXT: - "-ios class chain:**/XCUIElementTypeGroup/XCUIElementTypeStaticText", + ENCRYPTED_MESSAGES_TEXT: "-ios class chain:**/XCUIElementTypeStaticText", TYPING_INDICATOR: "~message-typing-indicator", TYPING_INDICATOR_TEXT: "~typing-message", TYPING_INDICATOR_TEXT_VALUE: "-ios class chain:**/XCUIElementTypeStaticText", diff --git a/tests/specs/reusable-accounts/ChatUserB/01-main-chats-userB.spec.ts b/tests/specs/reusable-accounts/ChatUserB/01-main-chats-userB.spec.ts index 42dffed183a..e1fe058d65a 100644 --- a/tests/specs/reusable-accounts/ChatUserB/01-main-chats-userB.spec.ts +++ b/tests/specs/reusable-accounts/ChatUserB/01-main-chats-userB.spec.ts @@ -33,19 +33,14 @@ export default async function mainChatsTestsUserB() { // Validate friend request appears on pending list await friendsScreenFirstUser.hoverOnPendingListButton(); await friendsScreenFirstUser.goToPendingFriendsList(); - await friendsScreenFirstUser.validateOutgoingListIsShown(); - await friendsScreenFirstUser.validateOutgoingListIsNotEmpty(); - - await friendsScreenFirstUser.goToAllFriendsList(); - await friendsScreenFirstUser.validateAllFriendsListIsShown(); }); it("Chat User B - Validate friend request was accepted", async () => { // With User A - Go to pending requests list, wait for receiving the friend request and accept it + await friendsScreenFirstUser.goToAllFriendsList(); await friendsScreenFirstUser.waitUntilUserAcceptedFriendRequest(); // Validate friend is now on all friends list - await friendsScreenFirstUser.goToAllFriendsList(); await friendsScreenFirstUser.validateAllFriendsListIsShown(); await friendsScreenFirstUser.validateAllFriendsListIsNotEmpty(); }); From 8f2123a1a57f83c2b46673d04cb224761b6dd36e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Carden=CC=83a?= <35935591+luisecm@users.noreply.github.com> Date: Mon, 6 Nov 2023 22:18:32 -0600 Subject: [PATCH 16/22] test(update): update locator for button --- tests/screenobjects/chats/InputBar.ts | 4 ++-- .../reusable-accounts/ChatUserB/01-main-chats-userB.spec.ts | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/screenobjects/chats/InputBar.ts b/tests/screenobjects/chats/InputBar.ts index 72bdca3cea7..75f3cb1f02f 100644 --- a/tests/screenobjects/chats/InputBar.ts +++ b/tests/screenobjects/chats/InputBar.ts @@ -11,7 +11,7 @@ import { selectFileOnWindows, } from "@helpers/commands"; import UplinkMainScreen from "@screenobjects/UplinkMainScreen"; -const {keyboard, Key} = require("@nut-tree/nut-js"); +const { keyboard, Key } = require("@nut-tree/nut-js"); const currentOS = driver[USER_A_INSTANCE].capabilities.automationName; let SELECTORS = {}; @@ -38,7 +38,7 @@ const SELECTORS_WINDOWS = { const SELECTORS_MACOS = { EDIT_MESSAGE_INPUT: "~edit-message-input", EMOJI_BUTTON: - '-ios class chain:**/XCUIElementTypeGroup[`label == "chat-layout"`]/XCUIElementTypeButton[2]', + '-ios class chain:**/XCUIElementTypeGroup[`label == "chat-layout"`]/XCUIElementTypeGroup[8]/XCUIElementTypeButton', INPUT_CHAR_COUNTER: "~input-char-counter", INPUT_CHAR_COUNTER_TEXT: "-ios class chain:**/XCUIElementTypeStaticText", INPUT_CHAR_MAX_TEXT: diff --git a/tests/specs/reusable-accounts/ChatUserB/01-main-chats-userB.spec.ts b/tests/specs/reusable-accounts/ChatUserB/01-main-chats-userB.spec.ts index e1fe058d65a..cde1cc590a9 100644 --- a/tests/specs/reusable-accounts/ChatUserB/01-main-chats-userB.spec.ts +++ b/tests/specs/reusable-accounts/ChatUserB/01-main-chats-userB.spec.ts @@ -48,7 +48,6 @@ export default async function mainChatsTestsUserB() { it("Chat User B - Wait until the other user is connected", async () => { // Go to the current list of All friends and then open a Chat conversation with ChatUserA await friendsScreenFirstUser.validateChatWithFriendButtonExists(); - await friendsScreenFirstUser.hoverOnChatWithFriendButton("ChatUserA"); await friendsScreenFirstUser.chatWithFriendButton.click(); await chatsTopbarFirstUser.validateTopbarExists(); }); From 446e3f44bdb02c3c2e7b9c269955eabf6d8e4de5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Carden=CC=83a?= <35935591+luisecm@users.noreply.github.com> Date: Mon, 6 Nov 2023 23:14:04 -0600 Subject: [PATCH 17/22] screenobject(update): update waitUntil methods and click on emoji --- tests/helpers/commands.ts | 28 +++++++++---------- tests/screenobjects/chats/ChatsLayout.ts | 2 +- tests/screenobjects/chats/ChatsSidebar.ts | 10 +++++-- .../screenobjects/chats/ComposeAttachment.ts | 22 +++++++-------- tests/screenobjects/chats/CreateGroupChat.ts | 20 +++++++------ tests/screenobjects/chats/EditGroup.ts | 12 +++++--- tests/screenobjects/chats/EmojiSelector.ts | 3 +- tests/screenobjects/chats/FavoritesSidebar.ts | 25 ++++++++++------- tests/screenobjects/chats/MessageGroup.ts | 10 ++++--- tests/screenobjects/chats/Messages.ts | 16 +++++------ tests/screenobjects/chats/Topbar.ts | 10 +++---- tests/screenobjects/friends/FriendsScreen.ts | 24 ++++++++++------ 12 files changed, 103 insertions(+), 79 deletions(-) diff --git a/tests/helpers/commands.ts b/tests/helpers/commands.ts index 3886ed660d6..53da8dcdd3f 100644 --- a/tests/helpers/commands.ts +++ b/tests/helpers/commands.ts @@ -16,7 +16,7 @@ import { const { readFileSync, rmSync, writeFileSync } = require("fs"); const { execSync } = require("child_process"); const fsp = require("fs").promises; -const { mouse, Button } = require("@nut-tree/nut-js") +const { mouse, Button } = require("@nut-tree/nut-js"); let createPinFirstUser = new CreatePinScreen(USER_A_INSTANCE); let createPinSecondUser = new CreatePinScreen(USER_B_INSTANCE); let createUserFirstUser = new CreateUserScreen(USER_A_INSTANCE); @@ -35,7 +35,7 @@ export async function deleteCache() { console.log("Deleted user cache successfully"); } catch (error) { console.error( - `Got an error trying to delete the user cache files: ${error.message}` + `Got an error trying to delete the user cache files: ${error.message}`, ); } } @@ -50,7 +50,7 @@ export async function grabCacheFolder(username: string, instance: string) { console.log("Copied user cache successfully"); } catch (error) { console.error( - `Got an error trying to copy the user cache files: ${error.message}` + `Got an error trying to copy the user cache files: ${error.message}`, ); } } @@ -67,7 +67,7 @@ export async function loadTestUserData(user: string, instance: string) { console.log("Copied user cache successfully"); } catch (error) { console.error( - `Got an error trying to copy the user cache files: ${error.message}` + `Got an error trying to copy the user cache files: ${error.message}`, ); } } @@ -88,7 +88,7 @@ export async function getUserKey(username: string, instance: string) { export async function saveTestKeys( username: string, didkey: string, - instance: string + instance: string, ) { // Save JSON file with keys const currentDriver = await driver[instance].capabilities.automationName; @@ -263,7 +263,7 @@ export async function maximizeWindow(instance: string) { export async function clickOnSwitchMacOS( element: WebdriverIO.Element, - instance: string + instance: string, ) { const currentInstance = await browser.getInstance(instance); const elementLocator = await currentInstance.$(element); @@ -288,7 +288,7 @@ export async function getClipboardMacOS() { export async function hoverOnMacOS( locator: WebdriverIO.Element, - instance: string + instance: string, ) { // Hover on X and Y coordinates previously retrieved await driver[instance].executeScript("macos: hover", [ @@ -323,7 +323,7 @@ export async function saveFileOnMacOS(filename: string, instance: string) { export async function selectFileOnMacos( relativePath: string, - instance: string + instance: string, ) { const currentInstance = await browser.getInstance(instance); @@ -366,7 +366,7 @@ export async function selectFileOnMacos( export async function rightClickOnMacOS( locator: WebdriverIO.Element, - instance: string + instance: string, ) { await driver[instance].executeScript("macos: rightClick", [ { @@ -379,14 +379,14 @@ export async function rightClickOnMacOS( export async function hoverOnWindows( locator: WebdriverIO.Element, - instance: string + instance: string, ) { await driver[instance].moveToElement(locator.elementId); } export async function rightClickOnWindows( locator: WebdriverIO.Element, - instance: string + instance: string, ) { await driver[instance].moveToElement(locator.elementId); await mouse.click(Button.RIGHT); @@ -395,7 +395,7 @@ export async function rightClickOnWindows( export async function saveFileOnWindows( filename: string, uplinkContext: string, - instance: string + instance: string, ) { // Get the filepath to select on browser const filepath = join(process.cwd(), "\\tests\\fixtures\\", filename); @@ -415,7 +415,7 @@ export async function saveFileOnWindows( // Type file location and hit enter const editInput = await driver[instance].$( - "/Window/Pane[1]/ComboBox[1]/Edit" + "/Window/Pane[1]/ComboBox[1]/Edit", ); await editInput.clearValue(); await editInput.setValue(filename + "\uE007"); @@ -429,7 +429,7 @@ export async function saveFileOnWindows( export async function selectFileOnWindows( relativePath: string, uplinkContext: string, - instance: string + instance: string, ) { // Get the filepath to select on browser const filepath = join(process.cwd(), relativePath); diff --git a/tests/screenobjects/chats/ChatsLayout.ts b/tests/screenobjects/chats/ChatsLayout.ts index 6e405f6753c..c17e5a48d74 100644 --- a/tests/screenobjects/chats/ChatsLayout.ts +++ b/tests/screenobjects/chats/ChatsLayout.ts @@ -72,7 +72,7 @@ export default class ChatsLayout extends UplinkMainScreen { async validateChatLayoutIsShown() { await driver[this.executor].waitUntil( async () => { - return await this.chatLayout; + return await this.chatLayout.waitForExist(); }, { timeout: 15000, diff --git a/tests/screenobjects/chats/ChatsSidebar.ts b/tests/screenobjects/chats/ChatsSidebar.ts index 0a93675dd00..97cc8c1d4c9 100644 --- a/tests/screenobjects/chats/ChatsSidebar.ts +++ b/tests/screenobjects/chats/ChatsSidebar.ts @@ -415,7 +415,7 @@ export default class ChatsSidebar extends UplinkMainScreen { async waitForReceivingMessageOnSidebar() { await driver[this.executor].waitUntil( async () => { - return await this.sidebarChatsUserStatusValue; + return await this.sidebarChatsUserStatusValue.waitForExist(); }, { timeout: 60000, @@ -456,7 +456,10 @@ export default class ChatsSidebar extends UplinkMainScreen { const element = await this.getExistingElementByAriaLabel(groupname); await driver[this.executor].waitUntil( async () => { - return await this.instance.$(SELECTORS.SIDEBAR).$(element); + return await this.instance + .$(SELECTORS.SIDEBAR) + .$(element) + .waitForExist(); }, { timeout: 60000, @@ -548,7 +551,8 @@ export default class ChatsSidebar extends UplinkMainScreen { return await userLocator .$(SELECTORS.SIDEBAR_CHATS_USER_IMAGE_WRAP) .$(SELECTORS.SIDEBAR_CHATS_USER_IMAGE) - .$(SELECTORS.SIDEBAR_CHATS_USER_ONLINE_INDICATOR); + .$(SELECTORS.SIDEBAR_CHATS_USER_ONLINE_INDICATOR) + .waitForExist(); }, { timeout: 60000, diff --git a/tests/screenobjects/chats/ComposeAttachment.ts b/tests/screenobjects/chats/ComposeAttachment.ts index 871c200463c..e2a0cdfc717 100644 --- a/tests/screenobjects/chats/ComposeAttachment.ts +++ b/tests/screenobjects/chats/ComposeAttachment.ts @@ -58,25 +58,25 @@ export default class ComposeAttachments extends UplinkMainScreen { get composeAttachmentsFileIcon() { return this.composeAttachmentsFileEmbed.$( - SELECTORS.COMPOSE_ATTACHMENTS_FILE_ICON + SELECTORS.COMPOSE_ATTACHMENTS_FILE_ICON, ); } get composeAttachmentsFileInfo() { return this.composeAttachmentsFileEmbed.$( - SELECTORS.COMPOSE_ATTACHMENTS_FILE_INFO + SELECTORS.COMPOSE_ATTACHMENTS_FILE_INFO, ); } get composeAttachmentsFileMeta() { return this.composeAttachmentsFileEmbed.$( - SELECTORS.COMPOSE_ATTACHMENTS_FILE_META + SELECTORS.COMPOSE_ATTACHMENTS_FILE_META, ); } get composeAttachmentsFileName() { return this.composeAttachmentsFileEmbed.$( - SELECTORS.COMPOSE_ATTACHMENTS_FILE_NAME + SELECTORS.COMPOSE_ATTACHMENTS_FILE_NAME, ); } @@ -92,17 +92,17 @@ export default class ComposeAttachments extends UplinkMainScreen { get composeAttachmentsInputErrorText() { return this.composeAttachmentsInputError.$( - SELECTORS.COMPOSE_ATTACHMENTS_INPUT_ERROR_TEXT + SELECTORS.COMPOSE_ATTACHMENTS_INPUT_ERROR_TEXT, ); } async clickOnDeleteAttachment(attachment: number) { // Get the locator of attachment to delete by passing the index const attachmentToDelete = await this.instance.$$( - SELECTORS.COMPOSE_ATTACHMENTS_FILE_EMBED + SELECTORS.COMPOSE_ATTACHMENTS_FILE_EMBED, )[attachment]; const deleteAttachmentButton = await attachmentToDelete.$( - SELECTORS.COMPOSE_ATTACHMENTS_BUTTON + SELECTORS.COMPOSE_ATTACHMENTS_BUTTON, ); await deleteAttachmentButton.click(); } @@ -116,7 +116,7 @@ export default class ComposeAttachments extends UplinkMainScreen { const composeAttachments = await this.composeAttachments; await composeAttachments.waitForExist(); const filesAttached = await this.instance.$$( - SELECTORS.COMPOSE_ATTACHMENTS_FILE_EMBED + SELECTORS.COMPOSE_ATTACHMENTS_FILE_EMBED, ); let results = []; for (let fileAttached of filesAttached) { @@ -134,18 +134,18 @@ export default class ComposeAttachments extends UplinkMainScreen { const composeAttachmentsFileEmbed = await this.composeAttachmentsFileEmbed; await driver[this.executor].waitUntil( async () => { - return await composeAttachmentsFileEmbed; + return await composeAttachmentsFileEmbed.waitForExist(); }, { timeout: 15000, timeoutMsg: "Attachment file was not added after 15 seconds", - } + }, ); } async validateAttachmentWithFileNameIsAdded( fileName: string, - expectedAssertion: boolean + expectedAssertion: boolean, ) { const attachmentsList = await this.getListOfAttachmentsEmbed(); const includesAttachment = await attachmentsList.includes(fileName); diff --git a/tests/screenobjects/chats/CreateGroupChat.ts b/tests/screenobjects/chats/CreateGroupChat.ts index 0ad4f578df1..f07728f0d31 100644 --- a/tests/screenobjects/chats/CreateGroupChat.ts +++ b/tests/screenobjects/chats/CreateGroupChat.ts @@ -1,4 +1,4 @@ -const {keyboard, Key} = require("@nut-tree/nut-js"); +const { keyboard, Key } = require("@nut-tree/nut-js"); import "module-alias/register"; import { getClipboardMacOS } from "@helpers/commands"; import { @@ -187,7 +187,7 @@ export default class CreateGroupChat extends UplinkMainScreen { async getFriendFromListIndicatorOffline(username: string) { const friendLocator = await this.getFriendFromListLocator(username); const indicatorOffline = await friendLocator.$( - SELECTORS.FRIEND_INDICATOR_OFFLINE + SELECTORS.FRIEND_INDICATOR_OFFLINE, ); await indicatorOffline.waitForExist(); return indicatorOffline; @@ -197,17 +197,19 @@ export default class CreateGroupChat extends UplinkMainScreen { const friendLocator = await this.getFriendFromListLocator(username); await driver[this.executor].waitUntil( async () => { - return await friendLocator.$(SELECTORS.FRIEND_INDICATOR_ONLINE); + return await friendLocator + .$(SELECTORS.FRIEND_INDICATOR_ONLINE) + .waitForExist(); }, { timeout: 15000, timeoutMsg: "Expected indicator online was never displayed on Create Group Users List after 15 seconds", - } + }, ); const indicatorOnline = await friendLocator.$( - SELECTORS.FRIEND_INDICATOR_ONLINE + SELECTORS.FRIEND_INDICATOR_ONLINE, ); return indicatorOnline; } @@ -215,7 +217,7 @@ export default class CreateGroupChat extends UplinkMainScreen { async getFriendFromListUserImageProfile(username: string) { const friendLocator = await this.getFriendFromListLocator(username); const userImageProfile = await friendLocator.$( - SELECTORS.FRIEND_USER_IMAGE_PROFILE + SELECTORS.FRIEND_USER_IMAGE_PROFILE, ); await userImageProfile.waitForExist(); return userImageProfile; @@ -231,7 +233,7 @@ export default class CreateGroupChat extends UplinkMainScreen { .$( '//XCUIElementTypeGroup[@label="friend-name"]/XCUIElementTypeStaticText[contains(@value, "' + username + - '")]/../..' + '")]/../..', ); } else if (currentDriver === WINDOWS_DRIVER) { friendLocator = await this.instance @@ -240,7 +242,7 @@ export default class CreateGroupChat extends UplinkMainScreen { .$( '//Group[@Name="friend-name"]/Text[contains(@Name, "' + username + - '")]/../..' + '")]/../..', ); } return friendLocator; @@ -256,7 +258,7 @@ export default class CreateGroupChat extends UplinkMainScreen { async getFriendFromListUserImageWrap(username: string) { const friendLocator = await this.getFriendFromListLocator(username); const userImageWrap = await friendLocator.$( - SELECTORS.FRIEND_USER_IMAGE_WRAP + SELECTORS.FRIEND_USER_IMAGE_WRAP, ); await userImageWrap.waitForExist(); return userImageWrap; diff --git a/tests/screenobjects/chats/EditGroup.ts b/tests/screenobjects/chats/EditGroup.ts index 4ab5e7463f9..1f8f15a9518 100644 --- a/tests/screenobjects/chats/EditGroup.ts +++ b/tests/screenobjects/chats/EditGroup.ts @@ -251,7 +251,7 @@ export default class EditGroup extends UplinkMainScreen { )[0]; await driver[this.executor].waitUntil( async () => { - return await firstAddButton; + return await firstAddButton.waitForExist(); }, { timeout: 15000, @@ -268,7 +268,7 @@ export default class EditGroup extends UplinkMainScreen { )[0]; await driver[this.executor].waitUntil( async () => { - return await removeParticipantButton; + return await removeParticipantButton.waitForExist(); }, { timeout: 15000, @@ -348,7 +348,9 @@ export default class EditGroup extends UplinkMainScreen { const userLocator = await this.getParticipantContainerLocator(participant); await driver[this.executor].waitUntil( async () => { - return await userLocator.$(SELECTORS.PARTICIPANT_USER_INDICATOR_ONLINE); + return await userLocator + .$(SELECTORS.PARTICIPANT_USER_INDICATOR_ONLINE) + .waitForExist(); }, { timeout: 60000, @@ -440,7 +442,9 @@ export default class EditGroup extends UplinkMainScreen { async validateParticipantIndicatorOnline(username: string) { await driver[this.executor].waitUntil( async () => { - return await this.getParticipantIndicatorOnline(username); + return await this.getParticipantIndicatorOnline( + username, + ).waitForExist(); }, { timeout: 60000, diff --git a/tests/screenobjects/chats/EmojiSelector.ts b/tests/screenobjects/chats/EmojiSelector.ts index 730f1892a3d..678592bb23d 100644 --- a/tests/screenobjects/chats/EmojiSelector.ts +++ b/tests/screenobjects/chats/EmojiSelector.ts @@ -5,6 +5,7 @@ import { USER_A_INSTANCE, } from "@helpers/constants"; import UplinkMainScreen from "@screenobjects/UplinkMainScreen"; +const { mouse, Button } = require("@nut-tree/nut-js"); const currentOS = driver[USER_A_INSTANCE].capabilities.automationName; let SELECTORS = {}; @@ -72,6 +73,6 @@ export default class EmojiSelector extends UplinkMainScreen { .$(emojiLocator); } await this.hoverOnElement(emojiElement); - await emojiElement.click(); + await mouse.click(Button.LEFT); } } diff --git a/tests/screenobjects/chats/FavoritesSidebar.ts b/tests/screenobjects/chats/FavoritesSidebar.ts index 12d497f8456..bcfcf7f24c0 100644 --- a/tests/screenobjects/chats/FavoritesSidebar.ts +++ b/tests/screenobjects/chats/FavoritesSidebar.ts @@ -185,7 +185,10 @@ export default class FavoritesSidebar extends UplinkMainScreen { } await driver[this.executor].waitUntil( async () => { - return await this.instance.$(SELECTORS.SLIMBAR).$(favoritesLocator); + return await this.instance + .$(SELECTORS.SLIMBAR) + .$(favoritesLocator) + .waitForExist(); }, { timeout: 15000, @@ -203,7 +206,9 @@ export default class FavoritesSidebar extends UplinkMainScreen { const favoriteLocator = await this.getFavoritesUserByAriaLabel(username); await driver[this.executor].waitUntil( async () => { - return await favoriteLocator.$(SELECTORS.FAVORITES_USER_IMAGE); + return await favoriteLocator + .$(SELECTORS.FAVORITES_USER_IMAGE) + .waitForExist(); }, { timeout: 15000, @@ -219,9 +224,9 @@ export default class FavoritesSidebar extends UplinkMainScreen { const favoriteLocator = await this.getFavoritesUserByAriaLabel(username); await driver[this.executor].waitUntil( async () => { - return await favoriteLocator.$( - SELECTORS.FAVORITES_USER_IMAGE_GROUP_WRAP, - ); + return await favoriteLocator + .$(SELECTORS.FAVORITES_USER_IMAGE_GROUP_WRAP) + .waitForExist(); }, { timeout: 15000, @@ -276,9 +281,9 @@ export default class FavoritesSidebar extends UplinkMainScreen { const favoriteLocator = await this.getFavoritesUserByAriaLabel(username); await driver[this.executor].waitUntil( async () => { - return await favoriteLocator.$( - SELECTORS.FAVORITES_USER_INDICATOR_ONLINE, - ); + return await favoriteLocator + .$(SELECTORS.FAVORITES_USER_INDICATOR_ONLINE) + .waitForExist(); }, { timeout: 60000, @@ -308,7 +313,7 @@ export default class FavoritesSidebar extends UplinkMainScreen { } await driver[this.executor].waitUntil( async () => { - return await this.contextMenu; + return await this.contextMenu.waitForExist(); }, { timeout: 15000, @@ -365,7 +370,7 @@ export default class FavoritesSidebar extends UplinkMainScreen { async validateFavoritesAreShown() { await driver[this.executor].waitUntil( async () => { - return await this.favorites; + return await this.favorites.waitForExist(); }, { timeout: 15000, diff --git a/tests/screenobjects/chats/MessageGroup.ts b/tests/screenobjects/chats/MessageGroup.ts index f40295e162d..8959b1d9ab5 100644 --- a/tests/screenobjects/chats/MessageGroup.ts +++ b/tests/screenobjects/chats/MessageGroup.ts @@ -300,7 +300,9 @@ export default class MessageGroup extends UplinkMainScreen { const lastGroupReceived = await this.getLastReceivedGroup(); await driver[this.executor].waitUntil( async () => { - return await lastGroupReceived.$(SELECTORS.PIN_INDICATOR); + return await lastGroupReceived + .$(SELECTORS.PIN_INDICATOR) + .waitForExist(); }, { timeout: 15000, @@ -334,7 +336,7 @@ export default class MessageGroup extends UplinkMainScreen { const lastGroupSent = await this.getLastSentGroup(); await driver[this.executor].waitUntil( async () => { - return await lastGroupSent.$(SELECTORS.PIN_INDICATOR); + return await lastGroupSent.$(SELECTORS.PIN_INDICATOR).waitForExist(); }, { timeout: 15000, @@ -468,7 +470,7 @@ export default class MessageGroup extends UplinkMainScreen { } await driver[this.executor].waitUntil( async () => { - return await this.instance.$(emojiReactionLocator); + return await this.instance.$(emojiReactionLocator).waitForExist(); }, { timeout: 60000, @@ -494,7 +496,7 @@ export default class MessageGroup extends UplinkMainScreen { } await driver[this.executor].waitUntil( async () => { - return await this.instance.$(emojiReactionLocator); + return await this.instance.$(emojiReactionLocator).waitForExist(); }, { timeout: 15000, diff --git a/tests/screenobjects/chats/Messages.ts b/tests/screenobjects/chats/Messages.ts index 649a8fd3c1e..8a85496cb07 100644 --- a/tests/screenobjects/chats/Messages.ts +++ b/tests/screenobjects/chats/Messages.ts @@ -352,7 +352,7 @@ export default class Messages extends UplinkMainScreen { } await driver[this.executor].waitUntil( async () => { - return await this.instance.$(locator); + return await this.instance.$(locator).waitForExist(); }, { timeout: 60000, @@ -413,7 +413,7 @@ export default class Messages extends UplinkMainScreen { } await driver[this.executor].waitUntil( async () => { - return await this.instance.$(codeMessageLocator); + return await this.instance.$(codeMessageLocator).waitForExist(); }, { timeout: 15000, @@ -467,7 +467,7 @@ export default class Messages extends UplinkMainScreen { } await driver[this.executor].waitUntil( async () => { - return await this.instance.$(linkSentLocator); + return await this.instance.$(linkSentLocator).waitForExist(); }, { timeout: 15000, @@ -493,7 +493,7 @@ export default class Messages extends UplinkMainScreen { } await driver[this.executor].waitUntil( async () => { - return await this.instance.$(messageSentLocator); + return await this.instance.$(messageSentLocator).waitForExist(); }, { timeout: 15000, @@ -519,7 +519,7 @@ export default class Messages extends UplinkMainScreen { await driver[this.executor].waitUntil( async () => { - return await this.instance.$(codeMessageReceivedLocator); + return await this.instance.$(codeMessageReceivedLocator).waitForExist(); }, { timeout: 60000, @@ -545,7 +545,7 @@ export default class Messages extends UplinkMainScreen { await driver[this.executor].waitUntil( async () => { - return await this.instance.$(linkReceivedLocator); + return await this.instance.$(linkReceivedLocator).waitForExist(); }, { timeout: 60000, @@ -571,7 +571,7 @@ export default class Messages extends UplinkMainScreen { await driver[this.executor].waitUntil( async () => { - return await this.instance.$(receivedMessageLocator); + return await this.instance.$(receivedMessageLocator).waitForExist(); }, { timeout: 60000, @@ -646,7 +646,7 @@ export default class Messages extends UplinkMainScreen { await driver[this.executor].waitUntil( async () => { - return await this.instance.$(messageSentLocator); + return await this.instance.$(messageSentLocator).waitForExist(); }, { timeout: 15000, diff --git a/tests/screenobjects/chats/Topbar.ts b/tests/screenobjects/chats/Topbar.ts index 9b3cc74d6fc..2428227967c 100644 --- a/tests/screenobjects/chats/Topbar.ts +++ b/tests/screenobjects/chats/Topbar.ts @@ -229,7 +229,7 @@ export default class Topbar extends UplinkMainScreen { await topbarAddToFavorites.click(); await driver[this.executor].waitUntil( async () => { - return await this.topbarRemoveFromFavorites; + return await this.topbarRemoveFromFavorites.waitForExist(); }, { timeout: 15000, @@ -295,7 +295,7 @@ export default class Topbar extends UplinkMainScreen { async validateTopbarIndicatorOnline() { await driver[this.executor].waitUntil( async () => { - return await this.topbarIndicatorOnline; + return await this.topbarIndicatorOnline.waitForExist(); }, { timeout: 60000, @@ -321,7 +321,7 @@ export default class Topbar extends UplinkMainScreen { async validateTopbarUserImage() { await driver[this.executor].waitUntil( async () => { - return await this.topbarUserImage; + return await this.topbarUserImage.waitForExist(); }, { timeout: 15000, @@ -334,7 +334,7 @@ export default class Topbar extends UplinkMainScreen { async validateTopbarExists() { await driver[this.executor].waitUntil( async () => { - return await this.topbar; + return await this.topbar.waitForExist(); }, { timeout: 15000, @@ -346,7 +346,7 @@ export default class Topbar extends UplinkMainScreen { async waitUntilRemoteUserIsOnline() { await driver[this.executor].waitUntil( async () => { - return await this.topbarIndicatorOnline; + return await this.topbarIndicatorOnline.waitForExist(); }, { timeout: 60000, diff --git a/tests/screenobjects/friends/FriendsScreen.ts b/tests/screenobjects/friends/FriendsScreen.ts index 96a3815afbc..d435cdf2337 100644 --- a/tests/screenobjects/friends/FriendsScreen.ts +++ b/tests/screenobjects/friends/FriendsScreen.ts @@ -611,7 +611,9 @@ export default class FriendsScreen extends UplinkMainScreen { const userLocator = await this.getExistingFriendByAriaLabel(username); await driver[this.executor].waitUntil( async () => { - return await userLocator.$(SELECTORS.FRIEND_USER_INDICATOR_ONLINE); + return await userLocator + .$(SELECTORS.FRIEND_USER_INDICATOR_ONLINE) + .waitForExist(); }, { timeout: 60000, @@ -725,7 +727,8 @@ export default class FriendsScreen extends UplinkMainScreen { async () => { return await this.instance .$(SELECTORS.FRIENDS_LIST) - .$(SELECTORS.FRIEND_INFO_USERNAME); + .$(SELECTORS.FRIEND_INFO_USERNAME) + .waitForExist(); }, { timeout: 60000, @@ -745,7 +748,8 @@ export default class FriendsScreen extends UplinkMainScreen { async () => { return await this.instance .$(SELECTORS.BLOCKED_LIST) - .$(SELECTORS.FRIEND_INFO_USERNAME); + .$(SELECTORS.FRIEND_INFO_USERNAME) + .waitForExist(); }, { timeout: 60000, @@ -769,7 +773,7 @@ export default class FriendsScreen extends UplinkMainScreen { // Wait until incoming list is not empty await driver[this.executor].waitUntil( async () => { - return await this.chatWithFriendButton; + return await this.chatWithFriendButton.waitForExist(); }, { timeout: 60000, @@ -794,7 +798,8 @@ export default class FriendsScreen extends UplinkMainScreen { async () => { return await this.instance .$(SELECTORS.INCOMING_REQUESTS_LIST) - .$(SELECTORS.FRIEND_INFO_USERNAME); + .$(SELECTORS.FRIEND_INFO_USERNAME) + .waitForExist(); }, { timeout: 60000, @@ -826,7 +831,8 @@ export default class FriendsScreen extends UplinkMainScreen { async () => { return await this.instance .$(SELECTORS.OUTGOING_REQUESTS_LIST) - .$(SELECTORS.FRIEND_INFO_USERNAME); + .$(SELECTORS.FRIEND_INFO_USERNAME) + .waitForExist(); }, { timeout: 60000, @@ -861,7 +867,7 @@ export default class FriendsScreen extends UplinkMainScreen { async waitUntilFriendRequestIsReceived() { await driver[this.executor].waitUntil( async () => { - return await this.acceptFriendRequestButton; + return await this.acceptFriendRequestButton.waitForExist(); }, { timeout: 240000, @@ -874,7 +880,7 @@ export default class FriendsScreen extends UplinkMainScreen { async waitUntilUserAcceptedFriendRequest() { await driver[this.executor].waitUntil( async () => { - return await this.chatWithFriendButton; + return await this.chatWithFriendButton.waitForExist(); }, { timeout: 240000, @@ -888,7 +894,7 @@ export default class FriendsScreen extends UplinkMainScreen { const user = await this.getExistingFriendByAriaLabel(username); await driver[this.executor].waitUntil( async () => { - return await user.$(SELECTORS.FRIEND_INFO_USERNAME); + return await user.$(SELECTORS.FRIEND_INFO_USERNAME).waitForExist(); }, { timeout: 60000, From 126333ef1a43ed9133156514c44574f8fe6eaaba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Carden=CC=83a?= <35935591+luisecm@users.noreply.github.com> Date: Tue, 7 Nov 2023 11:07:43 -0600 Subject: [PATCH 18/22] screenobject(update): add custom timeouts for methods --- tests/screenobjects/UplinkMainScreen.ts | 4 +- tests/screenobjects/chats/ChatsLayout.ts | 4 +- tests/screenobjects/chats/ChatsSidebar.ts | 59 ++--- .../screenobjects/chats/ComposeAttachment.ts | 14 +- tests/screenobjects/chats/ContextMenu.ts | 8 +- .../screenobjects/chats/ContextMenuSidebar.ts | 4 +- tests/screenobjects/chats/CreateGroupChat.ts | 42 ++-- tests/screenobjects/chats/EditGroup.ts | 81 ++++--- tests/screenobjects/chats/FavoritesSidebar.ts | 52 +++-- tests/screenobjects/chats/MessageGroup.ts | 68 +++--- tests/screenobjects/chats/Messages.ts | 202 ++++++++++-------- tests/screenobjects/chats/PinnedMessages.ts | 78 +++---- tests/screenobjects/chats/ReplyPrompt.ts | 29 +-- tests/screenobjects/chats/SendFiles.ts | 46 ++-- tests/screenobjects/chats/Topbar.ts | 39 ++-- tests/screenobjects/files/FilesScreen.ts | 28 +-- tests/screenobjects/friends/FriendsScreen.ts | 190 ++++++++-------- .../settings/SettingsGeneralScreen.ts | 4 +- .../settings/SettingsMessagesScreen.ts | 4 +- .../settings/SettingsNotificationsScreen.ts | 16 +- .../settings/SettingsProfileScreen.ts | 16 +- .../welcome-screen/WelcomeScreen.ts | 4 +- 22 files changed, 560 insertions(+), 432 deletions(-) diff --git a/tests/screenobjects/UplinkMainScreen.ts b/tests/screenobjects/UplinkMainScreen.ts index efe0d6e0794..9b53079ed59 100644 --- a/tests/screenobjects/UplinkMainScreen.ts +++ b/tests/screenobjects/UplinkMainScreen.ts @@ -318,9 +318,9 @@ export default class UplinkMainScreen extends AppScreen { await this.instance.switchToWindow(currentInstance); } - async showUplinkWindow() { + async showUplinkWindow(timeout: number = 15000) { const window = await this.instance.window; await window.click(); - await window.waitForExist(); + await window.waitForExist({ timeout: timeout }); } } diff --git a/tests/screenobjects/chats/ChatsLayout.ts b/tests/screenobjects/chats/ChatsLayout.ts index c17e5a48d74..8a9d9e98f88 100644 --- a/tests/screenobjects/chats/ChatsLayout.ts +++ b/tests/screenobjects/chats/ChatsLayout.ts @@ -69,10 +69,10 @@ export default class ChatsLayout extends UplinkMainScreen { .$(SELECTORS.TYPING_INDICATOR_TEXT_VALUE); } - async validateChatLayoutIsShown() { + async validateChatLayoutIsShown(timeout: number = 15000) { await driver[this.executor].waitUntil( async () => { - return await this.chatLayout.waitForExist(); + return await this.chatLayout.waitForExist({ timeout: timeout }); }, { timeout: 15000, diff --git a/tests/screenobjects/chats/ChatsSidebar.ts b/tests/screenobjects/chats/ChatsSidebar.ts index 97cc8c1d4c9..5719cb2c6d1 100644 --- a/tests/screenobjects/chats/ChatsSidebar.ts +++ b/tests/screenobjects/chats/ChatsSidebar.ts @@ -405,17 +405,19 @@ export default class ChatsSidebar extends UplinkMainScreen { await expect(usernameDisplayed).toHaveTextContaining(username); } - async validateSidebarChatsIsShown() { + async validateSidebarChatsIsShown(timeout: number = 15000) { const sidebarChats = await this.sidebarChatsUser; - await sidebarChats.waitForExist(); + await sidebarChats.waitForExist({ timeout: timeout }); } // Waiting methods - async waitForReceivingMessageOnSidebar() { + async waitForReceivingMessageOnSidebar(timeout: number = 15000) { await driver[this.executor].waitUntil( async () => { - return await this.sidebarChatsUserStatusValue.waitForExist(); + return await this.sidebarChatsUserStatusValue.waitForExist({ + timeout: timeout, + }); }, { timeout: 60000, @@ -427,7 +429,10 @@ export default class ChatsSidebar extends UplinkMainScreen { // Get Sidebar Group elements - async getExistingElementByAriaLabel(username: string) { + async getExistingElementByAriaLabel( + username: string, + timeout: number = 15000, + ) { const currentDriver = await this.getCurrentDriver(); let locator; if (currentDriver === macDriver) { @@ -437,7 +442,7 @@ export default class ChatsSidebar extends UplinkMainScreen { .$(SELECTORS.SIDEBAR) .$('[name="' + username + '"]'); } - await locator.waitForExist(); + await locator.waitForExist({ timeout: timeout }); return locator; } @@ -452,14 +457,14 @@ export default class ChatsSidebar extends UplinkMainScreen { return locator; } - async waitForGroupToBeCreated(groupname: string) { + async waitForGroupToBeCreated(groupname: string, timeout: number = 15000) { const element = await this.getExistingElementByAriaLabel(groupname); await driver[this.executor].waitUntil( async () => { return await this.instance .$(SELECTORS.SIDEBAR) .$(element) - .waitForExist(); + .waitForExist({ timeout: timeout }); }, { timeout: 60000, @@ -485,66 +490,72 @@ export default class ChatsSidebar extends UplinkMainScreen { ); } - async getSidebarGroupPlusSome(groupname: string) { + async getSidebarGroupPlusSome(groupname: string, timeout: number = 15000) { const groupLocator = await this.getExistingElementByAriaLabel(groupname); const plusSomeLocator = await groupLocator.$( SELECTORS.SIDEBAR_GROUP_CHAT_PLUS_SOME, ); - await plusSomeLocator.waitForExist(); + await plusSomeLocator.waitForExist({ timeout: timeout }); return plusSomeLocator; } - async getSidebarGroupStatus(groupname: string) { + async getSidebarGroupStatus(groupname: string, timeout: number = 15000) { const groupLocator = await this.getExistingElementByAriaLabel(groupname); const statusLocator = await groupLocator .$(SELECTORS.SIDEBAR_CHATS_USER_STATUS) .$(SELECTORS.SIDEBAR_CHATS_USER_STATUS_VALUE); - await statusLocator.waitForExist(); + await statusLocator.waitForExist({ timeout: timeout }); return statusLocator; } // Get Sidebar User elements - async getSidebarUserImage(username: string) { + async getSidebarUserImage(username: string, timeout: number = 15000) { const userLocator = await this.getExistingElementByAriaLabel(username); const imageLocator = await userLocator .$(SELECTORS.SIDEBAR_CHATS_USER_IMAGE_WRAP) .$(SELECTORS.SIDEBAR_CHATS_USER_IMAGE); - await imageLocator.waitForExist(); + await imageLocator.waitForExist({ timeout: timeout }); return imageLocator; } - async getSidebarUserStatus(username: string) { + async getSidebarUserStatus(username: string, timeout: number = 15000) { const userLocator = await this.getExistingElementByAriaLabel(username); const statusLocator = await userLocator .$(SELECTORS.SIDEBAR_CHATS_USER_INFO) .$(SELECTORS.SIDEBAR_CHATS_USER_STATUS) .$(SELECTORS.SIDEBAR_CHATS_USER_STATUS_VALUE); - await statusLocator.waitForExist(); + await statusLocator.waitForExist({ timeout: timeout }); return statusLocator; } - async getSidebarUserIndicator(username: string) { + async getSidebarUserIndicator(username: string, timeout: number = 15000) { const userLocator = await this.getExistingElementByAriaLabel(username); const indicatorLocator = await userLocator .$(SELECTORS.SIDEBAR_CHATS_USER_IMAGE_WRAP) .$(SELECTORS.SIDEBAR_CHATS_USER_IMAGE) .$(SELECTORS.SIDEBAR_CHATS_USER_INDICATOR); - await indicatorLocator.waitForExist(); + await indicatorLocator.waitForExist({ timeout: timeout }); return indicatorLocator; } - async getSidebarUserIndicatorOffline(username: string) { + async getSidebarUserIndicatorOffline( + username: string, + timeout: number = 15000, + ) { const userLocator = await this.getExistingElementByAriaLabel(username); const offlineLocator = await userLocator .$(SELECTORS.SIDEBAR_CHATS_USER_IMAGE_WRAP) .$(SELECTORS.SIDEBAR_CHATS_USER_IMAGE) .$(SELECTORS.SIDEBAR_CHATS_USER_OFFLINE_INDICATOR); - await offlineLocator.waitForExist(); + await offlineLocator.waitForExist({ timeout: timeout }); return offlineLocator; } - async getSidebarUserIndicatorOnline(username: string) { + async getSidebarUserIndicatorOnline( + username: string, + timeout: number = 15000, + ) { const userLocator = await this.getExistingElementByAriaLabel(username); await driver[this.executor].waitUntil( async () => { @@ -552,7 +563,7 @@ export default class ChatsSidebar extends UplinkMainScreen { .$(SELECTORS.SIDEBAR_CHATS_USER_IMAGE_WRAP) .$(SELECTORS.SIDEBAR_CHATS_USER_IMAGE) .$(SELECTORS.SIDEBAR_CHATS_USER_ONLINE_INDICATOR) - .waitForExist(); + .waitForExist({ timeout: timeout }); }, { timeout: 60000, @@ -568,13 +579,13 @@ export default class ChatsSidebar extends UplinkMainScreen { return onlineLocator; } - async getSidebarUserProfileTyping(username: string) { + async getSidebarUserProfileTyping(username: string, timeout: number = 15000) { const userLocator = await this.getExistingElementByAriaLabel(username); const profileTyping = await userLocator .$(SELECTORS.SIDEBAR_CHATS_USER_IMAGE_WRAP) .$(SELECTORS.SIDEBAR_CHATS_USER_IMAGE) .$(SELECTORS.SIDEBAR_CHATS_USER_PROFILE_TYPING); - await profileTyping.waitForExist(); + await profileTyping.waitForExist({ timeout: timeout }); return profileTyping; } diff --git a/tests/screenobjects/chats/ComposeAttachment.ts b/tests/screenobjects/chats/ComposeAttachment.ts index e2a0cdfc717..18ec6a31daf 100644 --- a/tests/screenobjects/chats/ComposeAttachment.ts +++ b/tests/screenobjects/chats/ComposeAttachment.ts @@ -112,9 +112,9 @@ export default class ComposeAttachments extends UplinkMainScreen { await composeAttachmentsButton.click(); } - async getListOfAttachmentsEmbed() { + async getListOfAttachmentsEmbed(timeout: number = 15000) { const composeAttachments = await this.composeAttachments; - await composeAttachments.waitForExist(); + await composeAttachments.waitForExist({ timeout: timeout }); const filesAttached = await this.instance.$$( SELECTORS.COMPOSE_ATTACHMENTS_FILE_EMBED, ); @@ -130,11 +130,13 @@ export default class ComposeAttachments extends UplinkMainScreen { return results; } - async validateAttachmentIsAdded() { + async validateAttachmentIsAdded(timeout: number = 15000) { const composeAttachmentsFileEmbed = await this.composeAttachmentsFileEmbed; await driver[this.executor].waitUntil( async () => { - return await composeAttachmentsFileEmbed.waitForExist(); + return await composeAttachmentsFileEmbed.waitForExist({ + timeout: timeout, + }); }, { timeout: 15000, @@ -152,8 +154,8 @@ export default class ComposeAttachments extends UplinkMainScreen { await expect(includesAttachment).toEqual(expectedAssertion); } - async validateComposeAttachmentsIsShown() { + async validateComposeAttachmentsIsShown(timeout: number = 15000) { const composeAttachments = await this.composeAttachments; - await composeAttachments.waitForExist(); + await composeAttachments.waitForExist({ timeout: timeout }); } } diff --git a/tests/screenobjects/chats/ContextMenu.ts b/tests/screenobjects/chats/ContextMenu.ts index f586f703494..e6f9dcbae48 100644 --- a/tests/screenobjects/chats/ContextMenu.ts +++ b/tests/screenobjects/chats/ContextMenu.ts @@ -152,11 +152,11 @@ export default class ContextMenu extends UplinkMainScreen { locator = await this.instance.$( '//XCUIElementTypeGroup[@label="Context Menu"]/XCUIElementTypeButton[@Value="' + reaction + - '"]' + '"]', ); } else if (currentDriver === WINDOWS_DRIVER) { locator = await this.instance.$( - '//Group[@Name="Context Menu"]/Button[@Name="' + reaction + '"]' + '//Group[@Name="Context Menu"]/Button[@Name="' + reaction + '"]', ); } await locator.click(); @@ -203,8 +203,8 @@ export default class ContextMenu extends UplinkMainScreen { await contextMessagesReply.click(); } - async validateContextMenuIsOpen() { + async validateContextMenuIsOpen(timeout: number = 15000) { const contextMenu = await this.contextMenu; - await contextMenu.waitForExist(); + await contextMenu.waitForExist({ timeout: timeout }); } } diff --git a/tests/screenobjects/chats/ContextMenuSidebar.ts b/tests/screenobjects/chats/ContextMenuSidebar.ts index e803ea80156..429ac24c70c 100644 --- a/tests/screenobjects/chats/ContextMenuSidebar.ts +++ b/tests/screenobjects/chats/ContextMenuSidebar.ts @@ -84,8 +84,8 @@ export default class ContextMenuSidebar extends UplinkMainScreen { await leaveGroup.click(); } - async validateContextMenuIsOpen() { + async validateContextMenuIsOpen(timeout: number = 15000) { const contextMenu = await this.contextMenu; - await contextMenu.waitForExist(); + await contextMenu.waitForExist({ timeout: timeout }); } } diff --git a/tests/screenobjects/chats/CreateGroupChat.ts b/tests/screenobjects/chats/CreateGroupChat.ts index f07728f0d31..310cb06f0d1 100644 --- a/tests/screenobjects/chats/CreateGroupChat.ts +++ b/tests/screenobjects/chats/CreateGroupChat.ts @@ -177,29 +177,35 @@ export default class CreateGroupChat extends UplinkMainScreen { await createGroupChatButton.click(); } - async getFriendFromListIndicator(username: string) { + async getFriendFromListIndicator(username: string, timeout: number = 15000) { const friendLocator = await this.getFriendFromListLocator(username); const indicator = await friendLocator.$(SELECTORS.FRIEND_INDICATOR); - await indicator.waitForExist(); + await indicator.waitForExist({ timeout: timeout }); return indicator; } - async getFriendFromListIndicatorOffline(username: string) { + async getFriendFromListIndicatorOffline( + username: string, + timeout: number = 15000, + ) { const friendLocator = await this.getFriendFromListLocator(username); const indicatorOffline = await friendLocator.$( SELECTORS.FRIEND_INDICATOR_OFFLINE, ); - await indicatorOffline.waitForExist(); + await indicatorOffline.waitForExist({ timeout: timeout }); return indicatorOffline; } - async getFriendFromListIndicatorOnline(username: string) { + async getFriendFromListIndicatorOnline( + username: string, + timeout: number = 15000, + ) { const friendLocator = await this.getFriendFromListLocator(username); await driver[this.executor].waitUntil( async () => { return await friendLocator .$(SELECTORS.FRIEND_INDICATOR_ONLINE) - .waitForExist(); + .waitForExist({ timeout: timeout }); }, { timeout: 15000, @@ -214,12 +220,15 @@ export default class CreateGroupChat extends UplinkMainScreen { return indicatorOnline; } - async getFriendFromListUserImageProfile(username: string) { + async getFriendFromListUserImageProfile( + username: string, + timeout: number = 15000, + ) { const friendLocator = await this.getFriendFromListLocator(username); const userImageProfile = await friendLocator.$( SELECTORS.FRIEND_USER_IMAGE_PROFILE, ); - await userImageProfile.waitForExist(); + await userImageProfile.waitForExist({ timeout: timeout }); return userImageProfile; } @@ -248,19 +257,22 @@ export default class CreateGroupChat extends UplinkMainScreen { return friendLocator; } - async getFriendFromListUserImage(username: string) { + async getFriendFromListUserImage(username: string, timeout: number = 15000) { const friendLocator = await this.getFriendFromListLocator(username); const userImage = await friendLocator.$(SELECTORS.FRIEND_USER_IMAGE); - await userImage.waitForExist(); + await userImage.waitForExist({ timeout: timeout }); return userImage; } - async getFriendFromListUserImageWrap(username: string) { + async getFriendFromListUserImageWrap( + username: string, + timeout: number = 15000, + ) { const friendLocator = await this.getFriendFromListLocator(username); const userImageWrap = await friendLocator.$( SELECTORS.FRIEND_USER_IMAGE_WRAP, ); - await userImageWrap.waitForExist(); + await userImageWrap.waitForExist({ timeout: timeout }); return userImageWrap; } @@ -269,7 +281,7 @@ export default class CreateGroupChat extends UplinkMainScreen { const usernameLocator = await friendLocator .$(SELECTORS.FRIEND_USER_NAME) .$(SELECTORS.FRIEND_USER_NAME_TEXT); - await usernameLocator.waitForExist(); + await usernameLocator.waitForExist({ timeout: timeout }); return usernameLocator; } @@ -347,8 +359,8 @@ export default class CreateGroupChat extends UplinkMainScreen { return result.toString(); } - async validateCreateGroupChatsIsShown() { + async validateCreateGroupChatsIsShown(timeout: number = 15000) { const createGroupChatSection = await this.createGroupChatSection; - await createGroupChatSection.waitForExist(); + await createGroupChatSection.waitForExist({ timeout: timeout }); } } diff --git a/tests/screenobjects/chats/EditGroup.ts b/tests/screenobjects/chats/EditGroup.ts index 1f8f15a9518..13404228dcd 100644 --- a/tests/screenobjects/chats/EditGroup.ts +++ b/tests/screenobjects/chats/EditGroup.ts @@ -245,13 +245,13 @@ export default class EditGroup extends UplinkMainScreen { await currentMembers.click(); } - async clickOnFirstAddButton() { + async clickOnFirstAddButton(timeout: number = 15000) { const firstAddButton = await this.instance.$$( SELECTORS.ADD_PARTICIPANT_BUTTON, )[0]; await driver[this.executor].waitUntil( async () => { - return await firstAddButton.waitForExist(); + return await firstAddButton.waitForExist({ timeout: timeout }); }, { timeout: 15000, @@ -262,13 +262,13 @@ export default class EditGroup extends UplinkMainScreen { await firstAddButton.click(); } - async clickOnFirstRemoveButton() { + async clickOnFirstRemoveButton(timeout: number = 15000) { const removeParticipantButton = await this.instance.$$( SELECTORS.REMOVE_PARTICIPANT_BUTTON, )[0]; await driver[this.executor].waitUntil( async () => { - return await removeParticipantButton.waitForExist(); + return await removeParticipantButton.waitForExist({ timeout: timeout }); }, { timeout: 15000, @@ -328,29 +328,35 @@ export default class EditGroup extends UplinkMainScreen { return locator; } - async getParticipantIndicator(participant: string) { + async getParticipantIndicator(participant: string, timeout: number = 15000) { const userLocator = await this.getParticipantContainerLocator(participant); const indicator = await userLocator.$(SELECTORS.PARTICIPANT_USER_INDICATOR); - await indicator.waitForExist(); + await indicator.waitForExist({ timeout: timeout }); return indicator; } - async getParticipantIndicatorOffline(participant: string) { + async getParticipantIndicatorOffline( + participant: string, + timeout: number = 15000, + ) { const userLocator = await this.getParticipantContainerLocator(participant); const indicatorOffline = await userLocator.$( SELECTORS.PARTICIPANT_USER_INDICATOR_OFFLINE, ); - await indicatorOffline.waitForExist(); + await indicatorOffline.waitForExist({ timeout: timeout }); return indicatorOffline; } - async getParticipantIndicatorOnline(participant: string) { + async getParticipantIndicatorOnline( + participant: string, + timeout: number = 15000, + ) { const userLocator = await this.getParticipantContainerLocator(participant); await driver[this.executor].waitUntil( async () => { return await userLocator .$(SELECTORS.PARTICIPANT_USER_INDICATOR_ONLINE) - .waitForExist(); + .waitForExist({ timeout: timeout }); }, { timeout: 60000, @@ -365,46 +371,58 @@ export default class EditGroup extends UplinkMainScreen { return indicatorOnline; } - async getParticipantUserCreatorBadgeImage(participant: string) { + async getParticipantUserCreatorBadgeImage( + participant: string, + timeout: number = 15000, + ) { const userLocator = await this.getParticipantContainerLocator(participant); const badgeImage = await userLocator.$( SELECTORS.PARTICIPANT_USER_CREATOR_BADGE_IMAGE, ); - await badgeImage.waitForExist(); + await badgeImage.waitForExist({ timeout: timeout }); return badgeImage; } - async getParticipantUserCreatorBadgeText(participant: string) { + async getParticipantUserCreatorBadgeText( + participant: string, + timeout: number = 15000, + ) { const userLocator = await this.getParticipantContainerLocator(participant); const badgeText = await userLocator.$( SELECTORS.PARTICIPANT_USER_CREATOR_BADGE_TEXT, ); - await badgeText.waitForExist(); + await badgeText.waitForExist({ timeout: timeout }); return badgeText; } - async getParticipantUserImage(participant: string) { + async getParticipantUserImage(participant: string, timeout: number = 15000) { const userLocator = await this.getParticipantContainerLocator(participant); const userImage = await userLocator.$(SELECTORS.PARTICIPANT_USER_IMAGE); - await userImage.waitForExist(); + await userImage.waitForExist({ timeout: timeout }); return userImage; } - async getParticipantUserImageProfile(participant: string) { + async getParticipantUserImageProfile( + participant: string, + timeout: number = 15000, + ) { const userLocator = await this.getParticipantContainerLocator(participant); const userImageProfile = await userLocator.$( SELECTORS.PARTICIPANT_USER_IMAGE_PROFILE, ); - await userImageProfile.waitForExist(); + await userImageProfile.waitForExist({ timeout: timeout }); return userImageProfile; } - async getParticipantUserImageWrap(participant: string) { + async getParticipantUserImageWrap( + participant: string, + timeout: number = 15000, + ) { const userLocator = await this.getParticipantContainerLocator(participant); const userImageWrap = await userLocator.$( SELECTORS.PARTICIPANT_USER_IMAGE_WRAP, ); - await userImageWrap.waitForExist(); + await userImageWrap.waitForExist({ timeout: timeout }); return userImageWrap; } @@ -429,26 +447,29 @@ export default class EditGroup extends UplinkMainScreen { } } - async validateEditGroupIsShown() { + async validateEditGroupIsShown(timeout: number = 15000) { const editGroupSection = await this.editGroupSection; - await editGroupSection.waitForExist(); + await editGroupSection.waitForExist({ timeout: timeout }); } - async validateNothingHereIsDisplayed() { + async validateNothingHereIsDisplayed(timeout: number = 15000) { const nothingHereText = await this.nothingHereText; - await nothingHereText.waitForExist(); + await nothingHereText.waitForExist({ timeout: timeout }); } - async validateParticipantIndicatorOnline(username: string) { + async validateParticipantIndicatorOnline( + username: string, + timeout: number = 15000, + ) { await driver[this.executor].waitUntil( async () => { - return await this.getParticipantIndicatorOnline( - username, - ).waitForExist(); + return await this.getParticipantIndicatorOnline(username).waitForExist({ + timeout: timeout, + }); }, { - timeout: 60000, - timeoutMsg: "Expected chat layout was never displayed after 60 seconds", + timeout: timeout, + timeoutMsg: "Expected chat layout was never displayed", }, ); } diff --git a/tests/screenobjects/chats/FavoritesSidebar.ts b/tests/screenobjects/chats/FavoritesSidebar.ts index bcfcf7f24c0..639e7bef893 100644 --- a/tests/screenobjects/chats/FavoritesSidebar.ts +++ b/tests/screenobjects/chats/FavoritesSidebar.ts @@ -175,7 +175,7 @@ export default class FavoritesSidebar extends UplinkMainScreen { await favoritesRemove.click(); } - async getFavoritesUserByAriaLabel(username: string) { + async getFavoritesUserByAriaLabel(username: string, timeout: number = 15000) { const currentDriver = await this.getCurrentDriver(); let favoritesLocator: string = ""; if (currentDriver === MACOS_DRIVER) { @@ -188,7 +188,7 @@ export default class FavoritesSidebar extends UplinkMainScreen { return await this.instance .$(SELECTORS.SLIMBAR) .$(favoritesLocator) - .waitForExist(); + .waitForExist({ timeout: timeout }); }, { timeout: 15000, @@ -202,13 +202,13 @@ export default class FavoritesSidebar extends UplinkMainScreen { return favoritesElement; } - async getFavoritesUserImage(username: string) { + async getFavoritesUserImage(username: string, timeout: number = 15000) { const favoriteLocator = await this.getFavoritesUserByAriaLabel(username); await driver[this.executor].waitUntil( async () => { return await favoriteLocator .$(SELECTORS.FAVORITES_USER_IMAGE) - .waitForExist(); + .waitForExist({ timeout: timeout }); }, { timeout: 15000, @@ -220,13 +220,16 @@ export default class FavoritesSidebar extends UplinkMainScreen { return userImage; } - async getFavoritesUserImageGroupWrap(username: string) { + async getFavoritesUserImageGroupWrap( + username: string, + timeout: number = 15000, + ) { const favoriteLocator = await this.getFavoritesUserByAriaLabel(username); await driver[this.executor].waitUntil( async () => { return await favoriteLocator .$(SELECTORS.FAVORITES_USER_IMAGE_GROUP_WRAP) - .waitForExist(); + .waitForExist({ timeout: timeout }); }, { timeout: 15000, @@ -241,49 +244,58 @@ export default class FavoritesSidebar extends UplinkMainScreen { return userImageGroupWrap; } - async getFavoritesUserImageProfile(username: string) { + async getFavoritesUserImageProfile( + username: string, + timeout: number = 15000, + ) { const favoriteLocator = await this.getFavoritesUserByAriaLabel(username); const imageProfile = await favoriteLocator.$( SELECTORS.FAVORITES_USER_IMAGE_PROFILE, ); - await imageProfile.waitForExist(); + await imageProfile.waitForExist({ timeout: timeout }); return imageProfile; } - async getFavoritesUserImageWrap(username: string) { + async getFavoritesUserImageWrap(username: string, timeout: number = 15000) { const favoriteLocator = await this.getFavoritesUserByAriaLabel(username); const userImageWrap = await favoriteLocator.$( SELECTORS.FAVORITES_USER_IMAGE_WRAP, ); - await userImageWrap.waitForExist(); + await userImageWrap.waitForExist({ timeout: timeout }); return userImageWrap; } - async getFavoritesUserIndicator(username: string) { + async getFavoritesUserIndicator(username: string, timeout: number = 15000) { const favoriteLocator = await this.getFavoritesUserByAriaLabel(username); const indicator = await favoriteLocator.$( SELECTORS.FAVORITES_USER_INDICATOR, ); - await indicator.waitForExist(); + await indicator.waitForExist({ timeout: timeout }); return indicator; } - async getFavoritesUserIndicatorOffline(username: string) { + async getFavoritesUserIndicatorOffline( + username: string, + timeout: number = 15000, + ) { const favoriteLocator = await this.getFavoritesUserByAriaLabel(username); const indicatorOffline = await favoriteLocator.$( SELECTORS.FAVORITES_USER_INDICATOR_OFFLINE, ); - await indicatorOffline.waitForExist(); + await indicatorOffline.waitForExist({ timeout: timeout }); return indicatorOffline; } - async getFavoritesUserIndicatorOnline(username: string) { + async getFavoritesUserIndicatorOnline( + username: string, + timeout: number = 15000, + ) { const favoriteLocator = await this.getFavoritesUserByAriaLabel(username); await driver[this.executor].waitUntil( async () => { return await favoriteLocator .$(SELECTORS.FAVORITES_USER_INDICATOR_ONLINE) - .waitForExist(); + .waitForExist({ timeout: timeout }); }, { timeout: 60000, @@ -303,7 +315,7 @@ export default class FavoritesSidebar extends UplinkMainScreen { await this.hoverOnElement(favoritesBubble); } - async openContextMenuOnFavoritesUser(name: string) { + async openContextMenuOnFavoritesUser(name: string, timeout: number = 15000) { const userImageProfile = await this.getFavoritesUserImageProfile(name); const currentDriver = await this.getCurrentDriver(); if (currentDriver === MACOS_DRIVER) { @@ -313,7 +325,7 @@ export default class FavoritesSidebar extends UplinkMainScreen { } await driver[this.executor].waitUntil( async () => { - return await this.contextMenu.waitForExist(); + return await this.contextMenu.waitForExist({ timeout: timeout }); }, { timeout: 15000, @@ -367,10 +379,10 @@ export default class FavoritesSidebar extends UplinkMainScreen { await this.hoverOnElement(slimbarSettingsButton); } - async validateFavoritesAreShown() { + async validateFavoritesAreShown(timeout: number = 15000) { await driver[this.executor].waitUntil( async () => { - return await this.favorites.waitForExist(); + return await this.favorites.waitForExist({ timeout: timeout }); }, { timeout: 15000, diff --git a/tests/screenobjects/chats/MessageGroup.ts b/tests/screenobjects/chats/MessageGroup.ts index 8959b1d9ab5..8f53899b591 100644 --- a/tests/screenobjects/chats/MessageGroup.ts +++ b/tests/screenobjects/chats/MessageGroup.ts @@ -228,28 +228,28 @@ export default class MessageGroup extends UplinkMainScreen { return lastGroupWrap; } - async getLastGroupWrapReceivedImage() { + async getLastGroupWrapReceivedImage(timeout: number = 15000) { const groupWrap = await this.getLastGroupWrapReceived(); const userImage = await groupWrap .$(SELECTORS.MESSAGE_GROUP_USER_IMAGE_WRAP) .$(SELECTORS.MESSAGE_GROUP_USER_IMAGE); - await userImage.waitForExist(); + await userImage.waitForExist({ timeout: timeout }); return userImage; } - async getLastGroupWrapReceivedIndicator() { + async getLastGroupWrapReceivedIndicator(timeout: number = 15000) { const groupWrap = await this.getLastGroupWrapReceived(); const indicator = await groupWrap.$(SELECTORS.MESSAGE_GROUP_USER_INDICATOR); - await indicator.waitForExist(); + await indicator.waitForExist({ timeout: timeout }); return indicator; } - async getLastGroupWrapReceivedOnline() { + async getLastGroupWrapReceivedOnline(timeout: number = 15000) { const groupWrap = await this.getLastGroupWrapReceived(); const onlineStatus = await groupWrap.$( SELECTORS.MESSAGE_GROUP_USER_INDICATOR_ONLINE, ); - await onlineStatus.waitForExist(); + await onlineStatus.waitForExist({ timeout: timeout }); return onlineStatus; } @@ -262,28 +262,28 @@ export default class MessageGroup extends UplinkMainScreen { return lastGroupWrap; } - async getLastGroupWrapSentImage() { + async getLastGroupWrapSentImage(timeout: number = 15000) { const groupWrap = await this.getLastGroupWrapSent(); const userImage = await groupWrap .$(SELECTORS.MESSAGE_GROUP_USER_IMAGE_WRAP) .$(SELECTORS.MESSAGE_GROUP_USER_IMAGE); - await userImage.waitForExist(); + await userImage.waitForExist({ timeout: timeout }); return userImage; } - async getLastGroupWrapSentIndicator() { + async getLastGroupWrapSentIndicator(timeout: number = 15000) { const groupWrap = await this.getLastGroupWrapSent(); const indicator = await groupWrap.$(SELECTORS.MESSAGE_GROUP_USER_INDICATOR); - await indicator.waitForExist(); + await indicator.waitForExist({ timeout: timeout }); return indicator; } - async getLastGroupWrapSentOnline() { + async getLastGroupWrapSentOnline(timeout: number = 15000) { const groupWrap = await this.getLastGroupWrapSent(); const onlineStatus = await groupWrap.$( SELECTORS.MESSAGE_GROUP_USER_INDICATOR_ONLINE, ); - await onlineStatus.waitForExist(); + await onlineStatus.waitForExist({ timeout: timeout }); return onlineStatus; } @@ -296,13 +296,13 @@ export default class MessageGroup extends UplinkMainScreen { return lastGroupLocator; } - async getLastMessageReceivedPinIndicator() { + async getLastMessageReceivedPinIndicator(timeout: number = 15000) { const lastGroupReceived = await this.getLastReceivedGroup(); await driver[this.executor].waitUntil( async () => { return await lastGroupReceived .$(SELECTORS.PIN_INDICATOR) - .waitForExist(); + .waitForExist({ timeout: timeout }); }, { timeout: 15000, @@ -315,12 +315,12 @@ export default class MessageGroup extends UplinkMainScreen { return pinIndicator; } - async getLastMessageReceivedTimeAgo() { + async getLastMessageReceivedTimeAgo(timeout: number = 15000) { const lastGroupReceived = await this.getLastReceivedGroup(); const timeAgoText = await lastGroupReceived .$(SELECTORS.MESSAGE_GROUP_TIME_AGO) .$(SELECTORS.MESSAGE_GROUP_TIME_AGO_TEXT); - await timeAgoText.waitForExist(); + await timeAgoText.waitForExist({ timeout: timeout }); return timeAgoText; } @@ -332,11 +332,13 @@ export default class MessageGroup extends UplinkMainScreen { return lastGroupLocator; } - async getLastMessageSentPinIndicator() { + async getLastMessageSentPinIndicator(timeout: number = 15000) { const lastGroupSent = await this.getLastSentGroup(); await driver[this.executor].waitUntil( async () => { - return await lastGroupSent.$(SELECTORS.PIN_INDICATOR).waitForExist(); + return await lastGroupSent + .$(SELECTORS.PIN_INDICATOR) + .waitForExist({ timeout: timeout }); }, { timeout: 15000, @@ -349,12 +351,12 @@ export default class MessageGroup extends UplinkMainScreen { return pinIndicator; } - async getLastMessageSentTimeAgo() { + async getLastMessageSentTimeAgo(timeout: number = 15000) { const lastGroupSent = await this.getLastSentGroup(); const timeAgoText = await lastGroupSent .$(SELECTORS.MESSAGE_GROUP_TIME_AGO) .$(SELECTORS.MESSAGE_GROUP_TIME_AGO_TEXT); - await timeAgoText.waitForExist(); + await timeAgoText.waitForExist({ timeout: timeout }); return timeAgoText; } @@ -454,7 +456,10 @@ export default class MessageGroup extends UplinkMainScreen { return results; } - async waitUntilEmojiReactionRemoteExists(expectedReaction: string) { + async waitUntilEmojiReactionRemoteExists( + expectedReaction: string, + timeout: number = 15000, + ) { const currentDriver = await this.getCurrentDriver(); let emojiReactionLocator: string = ""; if (currentDriver === MACOS_DRIVER) { @@ -470,7 +475,9 @@ export default class MessageGroup extends UplinkMainScreen { } await driver[this.executor].waitUntil( async () => { - return await this.instance.$(emojiReactionLocator).waitForExist(); + return await this.instance + .$(emojiReactionLocator) + .waitForExist({ timeout: timeout }); }, { timeout: 60000, @@ -480,7 +487,10 @@ export default class MessageGroup extends UplinkMainScreen { ); } - async waitUntilEmojiReactionSelfExists(expectedReaction: string) { + async waitUntilEmojiReactionSelfExists( + expectedReaction: string, + timeout: number = 15000, + ) { const currentDriver = await this.getCurrentDriver(); let emojiReactionLocator: string = ""; if (currentDriver === MACOS_DRIVER) { @@ -496,7 +506,9 @@ export default class MessageGroup extends UplinkMainScreen { } await driver[this.executor].waitUntil( async () => { - return await this.instance.$(emojiReactionLocator).waitForExist(); + return await this.instance + .$(emojiReactionLocator) + .waitForExist({ timeout: timeout }); }, { timeout: 15000, @@ -534,12 +546,12 @@ export default class MessageGroup extends UplinkMainScreen { // Pin Indicator validations - async validateLastMessageReceivedHasPinIndicator() { + async validateLastMessageReceivedHasPinIndicator(timeout: number = 15000) { const pinIndicator = await this.getLastMessageReceivedPinIndicator(); - await pinIndicator.waitForExist(); + await pinIndicator.waitForExist({ timeout: timeout }); } - async validateLastMessageSentHasPinIndicator() { + async validateLastMessageSentHasPinIndicator(timeout: number = 15000) { const pinIndicator = await this.getLastMessageSentPinIndicator(); - await pinIndicator.waitForExist(); + await pinIndicator.waitForExist({ timeout: timeout }); } } diff --git a/tests/screenobjects/chats/Messages.ts b/tests/screenobjects/chats/Messages.ts index 8a85496cb07..e4ba55a37a5 100644 --- a/tests/screenobjects/chats/Messages.ts +++ b/tests/screenobjects/chats/Messages.ts @@ -314,12 +314,12 @@ export default class Messages extends UplinkMainScreen { return messageCodeLanguage; } - async getLastMessageReceivedCodePane() { + async getLastMessageReceivedCodePane(timeout: number = 15000) { const message = await this.getLastMessageReceivedLocator(); const messageCodePane = await message .$(SELECTORS.CHAT_MESSAGE_TEXT_GROUP) .$(SELECTORS.CHAT_MESSAGE_CODE_PANE); - await messageCodePane.waitForExist(); + await messageCodePane.waitForExist({ timeout: timeout }); return messageCodePane; } @@ -336,7 +336,10 @@ export default class Messages extends UplinkMainScreen { return messageResult; } - async getMessageReceivedLocator(expectedMessage: string) { + async getMessageReceivedLocator( + expectedMessage: string, + timeout: number = 60000, + ) { const currentDriver = await this.getCurrentDriver(); let locator: string = ""; if (currentDriver === MACOS_DRIVER) { @@ -352,11 +355,13 @@ export default class Messages extends UplinkMainScreen { } await driver[this.executor].waitUntil( async () => { - return await this.instance.$(locator).waitForExist(); + return await this.instance + .$(locator) + .waitForExist({ timeout: timeout }); }, { - timeout: 60000, - timeoutMsg: "Expected message was never received after 60 seconds", + timeout: timeout, + timeoutMsg: "Expected message was never received", }, ); const element = await this.instance.$(locator); @@ -370,12 +375,12 @@ export default class Messages extends UplinkMainScreen { return lastMessage; } - async getLastMessageReceivedText() { + async getLastMessageReceivedText(timeout: number = 15000) { const message = await this.getLastMessageReceivedLocator(); const messageText = await message .$(SELECTORS.CHAT_MESSAGE_TEXT_GROUP) .$(SELECTORS.CHAT_MESSAGE_TEXT_VALUE); - await messageText.waitForExist(); + await messageText.waitForExist({ timeout: timeout }); return messageText; } @@ -385,18 +390,18 @@ export default class Messages extends UplinkMainScreen { return firstMessage; } - async getFirstMessageReceivedText() { + async getFirstMessageReceivedText(timeout: number = 15000) { const message = await this.getFirstMessageReceivedLocator(); const messageText = await message .$(SELECTORS.CHAT_MESSAGE_TEXT_GROUP) .$(SELECTORS.CHAT_MESSAGE_TEXT_VALUE); - await messageText.waitForExist(); + await messageText.waitForExist({ timeout: timeout }); return messageText; } async waitForCodeMessageSentToExist( expectedLanguage: string, - timeoutMsg: number = 30000, + timeout: number = 15000, ) { const currentDriver = await this.getCurrentDriver(); let codeMessageLocator: string = ""; @@ -413,11 +418,13 @@ export default class Messages extends UplinkMainScreen { } await driver[this.executor].waitUntil( async () => { - return await this.instance.$(codeMessageLocator).waitForExist(); + return await this.instance + .$(codeMessageLocator) + .waitForExist({ timeout: timeout }); }, { - timeout: 15000, - timeoutMsg: "Expected code message was never sent after 15 seconds", + timeout: timeout, + timeoutMsg: "Expected code message was never sent after waiting", }, ); } @@ -451,7 +458,10 @@ export default class Messages extends UplinkMainScreen { ); } - async waitForLinkSentToExist(expectedMessage: string) { + async waitForLinkSentToExist( + expectedMessage: string, + timeout: number = 15000, + ) { const currentDriver = await this.getCurrentDriver(); let linkSentLocator: string = ""; if (currentDriver === MACOS_DRIVER) { @@ -467,17 +477,22 @@ export default class Messages extends UplinkMainScreen { } await driver[this.executor].waitUntil( async () => { - return await this.instance.$(linkSentLocator).waitForExist(); + return await this.instance + .$(linkSentLocator) + .waitForExist({ timeout: timeout }); }, { - timeout: 15000, + timeout: timeout, timeoutMsg: - "Expected chat message with link was not sent after 15 seconds", + "Expected chat message with link was not sent after waiting", }, ); } - async waitForMessageSentToExist(expectedMessage: string) { + async waitForMessageSentToExist( + expectedMessage: string, + timeout: number = 15000, + ) { const currentDriver = await this.getCurrentDriver(); let messageSentLocator: string = ""; if (currentDriver === MACOS_DRIVER) { @@ -493,16 +508,21 @@ export default class Messages extends UplinkMainScreen { } await driver[this.executor].waitUntil( async () => { - return await this.instance.$(messageSentLocator).waitForExist(); + return await this.instance + .$(messageSentLocator) + .waitForExist({ timeout: timeout }); }, { - timeout: 15000, - timeoutMsg: "Expected chat message was not sent after 15 seconds", + timeout: timeout, + timeoutMsg: "Expected chat message was not sent", }, ); } - async waitForReceivingCodeMessage(expectedLanguage: string) { + async waitForReceivingCodeMessage( + expectedLanguage: string, + timeout: number = 60000, + ) { const currentDriver = await this.getCurrentDriver(); let codeMessageReceivedLocator: string = ""; if (currentDriver === MACOS_DRIVER) { @@ -519,16 +539,18 @@ export default class Messages extends UplinkMainScreen { await driver[this.executor].waitUntil( async () => { - return await this.instance.$(codeMessageReceivedLocator).waitForExist(); + return await this.instance + .$(codeMessageReceivedLocator) + .waitForExist({ timeout: timeout }); }, { - timeout: 60000, - timeoutMsg: "Expected code message was not received after 60 seconds", + timeout: timeout, + timeoutMsg: "Expected code message was not received", }, ); } - async waitForReceivingLink(expectedMessage: string) { + async waitForReceivingLink(expectedMessage: string, timeout: number = 60000) { const currentDriver = await this.getCurrentDriver(); let linkReceivedLocator: string = ""; if (currentDriver === MACOS_DRIVER) { @@ -545,16 +567,21 @@ export default class Messages extends UplinkMainScreen { await driver[this.executor].waitUntil( async () => { - return await this.instance.$(linkReceivedLocator).waitForExist(); + return await this.instance + .$(linkReceivedLocator) + .waitForExist({ timeout: timeout }); }, { - timeout: 60000, - timeoutMsg: "Expected link message was not received after 60 seconds", + timeout: timeout, + timeoutMsg: "Expected link message was not received", }, ); } - async waitForReceivingMessage(expectedMessage: string) { + async waitForReceivingMessage( + expectedMessage: string, + timeout: number = 60000, + ) { const currentDriver = await this.getCurrentDriver(); let receivedMessageLocator: string = ""; if (currentDriver === MACOS_DRIVER) { @@ -571,11 +598,13 @@ export default class Messages extends UplinkMainScreen { await driver[this.executor].waitUntil( async () => { - return await this.instance.$(receivedMessageLocator).waitForExist(); + return await this.instance + .$(receivedMessageLocator) + .waitForExist({ timeout: timeout }); }, { - timeout: 60000, - timeoutMsg: "Expected chat message was not received after 60 seconds", + timeout: timeout, + timeoutMsg: "Expected chat message was not received", }, ); } @@ -588,31 +617,31 @@ export default class Messages extends UplinkMainScreen { await copyButton.click(); } - async getLastMessageSentCodeCopyButton() { + async getLastMessageSentCodeCopyButton(timeout: number = 15000) { const message = await this.getLastMessageSentLocator(); const messageCodeCopyButton = await message .$(SELECTORS.CHAT_MESSAGE_TEXT_GROUP) .$(SELECTORS.CHAT_MESSAGE_CODE_COPY_BUTTON); - await messageCodeCopyButton.waitForExist(); + await messageCodeCopyButton.waitForExist({ timeout: timeout }); return messageCodeCopyButton; } - async getLastMessageSentCodeLanguage() { + async getLastMessageSentCodeLanguage(timeout: number = 15000) { const message = await this.getLastMessageSentLocator(); const messageText = await message.$(SELECTORS.CHAT_MESSAGE_TEXT_GROUP); const messageCodeLanguage = await messageText.$( SELECTORS.CHAT_MESSAGE_CODE_LANGUAGE, ); - await messageCodeLanguage.waitForExist(); + await messageCodeLanguage.waitForExist({ timeout: timeout }); return messageCodeLanguage; } - async getLastMessageSentCodePane() { + async getLastMessageSentCodePane(timeout: number = 15000) { const message = await this.getLastMessageSentLocator(); const messageCodePane = await message .$(SELECTORS.CHAT_MESSAGE_TEXT_GROUP) .$(SELECTORS.CHAT_MESSAGE_CODE_PANE); - await messageCodePane.waitForExist(); + await messageCodePane.waitForExist({ timeout: timeout }); return messageCodePane; } @@ -629,7 +658,10 @@ export default class Messages extends UplinkMainScreen { return messageResult; } - async getMessageSentLocator(expectedMessage: string) { + async getMessageSentLocator( + expectedMessage: string, + timeout: number = 15000, + ) { const currentDriver = await this.getCurrentDriver(); let messageSentLocator: string = ""; if (currentDriver === MACOS_DRIVER) { @@ -646,11 +678,13 @@ export default class Messages extends UplinkMainScreen { await driver[this.executor].waitUntil( async () => { - return await this.instance.$(messageSentLocator).waitForExist(); + return await this.instance + .$(messageSentLocator) + .waitForExist({ timeout: timeout }); }, { - timeout: 15000, - timeoutMsg: "Expected chat message was not sent after 15 seconds", + timeout: timeout, + timeoutMsg: "Expected chat message was not sent", }, ); } @@ -662,12 +696,12 @@ export default class Messages extends UplinkMainScreen { return lastMessage; } - async getLastMessageSentText() { + async getLastMessageSentText(timeout: number = 15000) { const message = await this.getLastMessageSentLocator(); const messageText = await message .$(SELECTORS.CHAT_MESSAGE_TEXT_GROUP) .$(SELECTORS.CHAT_MESSAGE_TEXT_VALUE); - await messageText.waitForExist(); + await messageText.waitForExist({ timeout: timeout }); return messageText; } @@ -677,27 +711,27 @@ export default class Messages extends UplinkMainScreen { return firstMessage; } - async getFirstMessageSentText() { + async getFirstMessageSentText(timeout: number = 15000) { const message = await this.getFirstMessageSentLocator(); const messageText = await message .$(SELECTORS.CHAT_MESSAGE_TEXT_GROUP) .$(SELECTORS.CHAT_MESSAGE_TEXT_VALUE); - await messageText.waitForExist(); + await messageText.waitForExist({ timeout: timeout }); return messageText; } // Replies Methods - async getLastReply() { + async getLastReply(timeout: number = 15000) { const lastReply = await this.chatMessageReply; - await lastReply.waitForExist(); + await lastReply.waitForExist({ timeout: timeout }); return lastReply; } - async getLastReplyText() { + async getLastReplyText(timeout: number = 15000) { const lastGroup = await this.chatMessageReply; const lastReplyText = await lastGroup.$(SELECTORS.CHAT_MESSAGE_REPLY_TEXT); - await lastReplyText.waitForExist(); + await lastReplyText.waitForExist({ timeout: timeout }); return lastReplyText; } @@ -763,93 +797,93 @@ export default class Messages extends UplinkMainScreen { // Messages With Files Methods - async getLastMessageReceivedDownloadButton() { + async getLastMessageReceivedDownloadButton(timeout: number = 15000) { const lastMessage = await this.getLastMessageReceivedLocator(); const getLastMessageDownloadButton = await lastMessage.$( SELECTORS.CHAT_MESSAGE_FILE_BUTTON, ); - await getLastMessageDownloadButton.waitForExist(); + await getLastMessageDownloadButton.waitForExist({ timeout: timeout }); return getLastMessageDownloadButton; } - async getLastMessageReceivedFileEmbed() { + async getLastMessageReceivedFileEmbed(timeout: number = 15000) { const lastMessage = await this.getLastMessageReceivedLocator(); const lastMessageFileEmbed = await lastMessage.$( SELECTORS.CHAT_MESSAGE_FILE_EMBED_REMOTE, ); - await lastMessageFileEmbed.waitForExist(); + await lastMessageFileEmbed.waitForExist({ timeout: timeout }); return lastMessageFileEmbed; } - async getLastMessageReceivedFileIcon() { + async getLastMessageReceivedFileIcon(timeout: number = 15000) { const lastMessage = await this.getLastMessageReceivedLocator(); const lastMessageFileIcon = await lastMessage.$( SELECTORS.CHAT_MESSAGE_FILE_ICON, ); - await lastMessageFileIcon.waitForExist(); + await lastMessageFileIcon.waitForExist({ timeout: timeout }); return lastMessageFileIcon; } - async getLastMessageReceivedFileMeta() { + async getLastMessageReceivedFileMeta(timeout: number = 15000) { const lastMessage = await this.getLastMessageReceivedLocator(); const lastMessageFileMeta = await lastMessage .$(SELECTORS.CHAT_MESSAGE_FILE_META) .$(SELECTORS.CHAT_MESSAGE_FILE_META_TEXT); - await lastMessageFileMeta.waitForExist(); + await lastMessageFileMeta.waitForExist({ timeout: timeout }); return lastMessageFileMeta; } - async getLastMessageReceivedFileName() { + async getLastMessageReceivedFileName(timeout: number = 15000) { const lastMessage = await this.getLastMessageReceivedLocator(); const lastMessageFileName = await lastMessage .$(SELECTORS.CHAT_MESSAGE_FILE_NAME) .$(SELECTORS.CHAT_MESSAGE_FILE_NAME_TEXT); - await lastMessageFileName.waitForExist(); + await lastMessageFileName.waitForExist({ timeout: timeout }); return lastMessageFileName; } - async getLastMessageSentDownloadButton() { + async getLastMessageSentDownloadButton(timeout: number = 15000) { const lastMessage = await this.getLastMessageSentLocator(); const getLastMessageSentDownloadButton = await lastMessage.$( SELECTORS.CHAT_MESSAGE_FILE_BUTTON, ); - await getLastMessageSentDownloadButton.waitForExist(); + await getLastMessageSentDownloadButton.waitForExist({ timeout: timeout }); return getLastMessageSentDownloadButton; } - async getLastMessageSentFileEmbed() { + async getLastMessageSentFileEmbed(timeout: number = 15000) { const lastMessage = await this.getLastMessageSentLocator(); const lastMessageFileEmbed = await lastMessage.$( SELECTORS.CHAT_MESSAGE_FILE_EMBED, ); - await lastMessageFileEmbed.waitForExist(); + await lastMessageFileEmbed.waitForExist({ timeout: timeout }); return lastMessageFileEmbed; } - async getLastMessageSentFileIcon() { + async getLastMessageSentFileIcon(timeout: number = 15000) { const lastMessage = await this.getLastMessageSentLocator(); const lastMessageFileIcon = await lastMessage.$( SELECTORS.CHAT_MESSAGE_FILE_ICON, ); - await lastMessageFileIcon.waitForExist(); + await lastMessageFileIcon.waitForExist({ timeout: timeout }); return lastMessageFileIcon; } - async getLastMessageSentFileMeta() { + async getLastMessageSentFileMeta(timeout: number = 15000) { const lastMessage = await this.getLastMessageSentLocator(); const lastMessageFileMeta = await lastMessage .$(SELECTORS.CHAT_MESSAGE_FILE_META) .$(SELECTORS.CHAT_MESSAGE_FILE_META_TEXT); - await lastMessageFileMeta.waitForExist(); + await lastMessageFileMeta.waitForExist({ timeout: timeout }); return lastMessageFileMeta; } - async getLastMessageSentFileName() { + async getLastMessageSentFileName(timeout: number = 15000) { const lastMessage = await this.getLastMessageSentLocator(); const lastMessageFileName = await lastMessage .$(SELECTORS.CHAT_MESSAGE_FILE_NAME) .$(SELECTORS.CHAT_MESSAGE_FILE_NAME_TEXT); - await lastMessageFileName.waitForExist(); + await lastMessageFileName.waitForExist({ timeout: timeout }); return lastMessageFileName; } @@ -863,31 +897,31 @@ export default class Messages extends UplinkMainScreen { return lastMessageLinkEmbed; } - async getLastMessageReceivedLinkEmbedDetailsText() { + async getLastMessageReceivedLinkEmbedDetailsText(timeout: number = 15000) { const linkEmbedLastMessage = await this.getLastMessageReceivedLinkEmbed(); const linkEmbedDetailsText = await linkEmbedLastMessage .$(SELECTORS.CHAT_MESSAGE_LINK_EMBED_DETAILS) .$(SELECTORS.CHAT_MESSAGE_LINK_EMBED_DETAILS_TEXT); - await linkEmbedDetailsText.waitForExist(); + await linkEmbedDetailsText.waitForExist({ timeout: timeout }); return linkEmbedDetailsText; } - async getLastMessageReceivedLinkEmbedIcon() { + async getLastMessageReceivedLinkEmbedIcon(timeout: number = 15000) { const linkEmbedLastMessage = await this.getLastMessageReceivedLinkEmbed(); const linkEmbedIcon = await linkEmbedLastMessage.$( SELECTORS.CHAT_MESSAGE_LINK_EMBED_ICON, ); - await linkEmbedIcon.waitForExist(); + await linkEmbedIcon.waitForExist({ timeout: timeout }); return linkEmbedIcon; } - async getLastMessageReceivedLinkEmbedIconTitle() { + async getLastMessageReceivedLinkEmbedIconTitle(timeout: number = 15000) { const linkEmbedIconLastMessage = await this.getLastMessageReceivedLinkEmbedIcon(); const iconTitle = await linkEmbedIconLastMessage.$( SELECTORS.CHAT_MESSAGE_LINK_EMBED_TITLE, ); - await iconTitle.waitForExist(); + await iconTitle.waitForExist({ timeout: timeout }); return iconTitle; } @@ -900,31 +934,31 @@ export default class Messages extends UplinkMainScreen { return lastMessageLinkEmbed; } - async getLastMessageSentLinkEmbedDetailsText() { + async getLastMessageSentLinkEmbedDetailsText(timeout: number = 15000) { const linkEmbedLastMessage = await this.getLastMessageSentLinkEmbed(); const linkEmbedDetailsText = await linkEmbedLastMessage .$(SELECTORS.CHAT_MESSAGE_LINK_EMBED_DETAILS) .$(SELECTORS.CHAT_MESSAGE_LINK_EMBED_DETAILS_TEXT); - await linkEmbedDetailsText.waitForExist(); + await linkEmbedDetailsText.waitForExist({ timeout: timeout }); return linkEmbedDetailsText; } - async getLastMessageSentLinkEmbedIcon() { + async getLastMessageSentLinkEmbedIcon(timeout: number = 15000) { const linkEmbedLastMessage = await this.getLastMessageSentLinkEmbed(); const linkEmbedIcon = await linkEmbedLastMessage.$( SELECTORS.CHAT_MESSAGE_LINK_EMBED_ICON, ); - await linkEmbedIcon.waitForExist(); + await linkEmbedIcon.waitForExist({ timeout: timeout }); return linkEmbedIcon; } - async getLastMessageSentLinkEmbedIconTitle() { + async getLastMessageSentLinkEmbedIconTitle(timeout: number = 15000) { const linkEmbedIconLastMessage = await this.getLastMessageSentLinkEmbedIcon(); const iconTitle = await linkEmbedIconLastMessage.$( SELECTORS.CHAT_MESSAGE_LINK_EMBED_TITLE, ); - await iconTitle.waitForExist(); + await iconTitle.waitForExist({ timeout: timeout }); return iconTitle; } diff --git a/tests/screenobjects/chats/PinnedMessages.ts b/tests/screenobjects/chats/PinnedMessages.ts index 2b35c139be2..e461de2a987 100644 --- a/tests/screenobjects/chats/PinnedMessages.ts +++ b/tests/screenobjects/chats/PinnedMessages.ts @@ -88,49 +88,49 @@ export default class PinnedMessages extends UplinkMainScreen { get pinnedMessageAttachmentsFileEmbed() { return this.pinnedMessageAttachments.$( - SELECTORS.PINNED_MESSAGE_ATTACHMENTS_FILE_EMBED + SELECTORS.PINNED_MESSAGE_ATTACHMENTS_FILE_EMBED, ); } get pinnedMessageAttachmentsFileIcon() { return this.pinnedMessageAttachmentsFileEmbed.$( - SELECTORS.PINNED_MESSAGE_ATTACHMENTS_FILE_ICON + SELECTORS.PINNED_MESSAGE_ATTACHMENTS_FILE_ICON, ); } get pinnedMessageAttachmentsFileIconExtension() { return this.pinnedMessageAttachmentsFileIcon.$( - SELECTORS.PINNED_MESSAGE_ATTACHMENTS_FILE_ICON_EXTENSION + SELECTORS.PINNED_MESSAGE_ATTACHMENTS_FILE_ICON_EXTENSION, ); } get pinnedMessageAttachmentsFileInfo() { return this.pinnedMessageAttachmentsFileEmbed.$( - SELECTORS.PINNED_MESSAGE_ATTACHMENTS_FILE_INFO + SELECTORS.PINNED_MESSAGE_ATTACHMENTS_FILE_INFO, ); } get pinnedMessageAttachmentsFileMeta() { return this.pinnedMessageAttachmentsFileInfo.$( - SELECTORS.PINNED_MESSAGE_ATTACHMENTS_FILE_META + SELECTORS.PINNED_MESSAGE_ATTACHMENTS_FILE_META, ); } get pinnedMessageAttachmentsFileMetaText() { return this.pinnedMessageAttachmentsFileMeta.$( - SELECTORS.PINNED_MESSAGE_ATTACHMENTS_FILE_META_TEXT + SELECTORS.PINNED_MESSAGE_ATTACHMENTS_FILE_META_TEXT, ); } get pinnedMessageAttachmentsFileName() { return this.pinnedMessageAttachmentsFileInfo.$( - SELECTORS.PINNED_MESSAGE_ATTACHMENTS_FILE_NAME + SELECTORS.PINNED_MESSAGE_ATTACHMENTS_FILE_NAME, ); } get pinnedMessageAttachmentsFileNameText() { return this.pinnedMessageAttachmentsFileName.$( - SELECTORS.PINNED_MESSAGE_ATTACHMENTS_FILE_NAME_TEXT + SELECTORS.PINNED_MESSAGE_ATTACHMENTS_FILE_NAME_TEXT, ); } @@ -164,19 +164,19 @@ export default class PinnedMessages extends UplinkMainScreen { get pinnedMessageTimestampText() { return this.pinnedMessageTimestamp.$( - SELECTORS.PINNED_MESSAGE_TIMESTAMP_TEXT + SELECTORS.PINNED_MESSAGE_TIMESTAMP_TEXT, ); } get pinnedMessageUserImage() { return this.pinnedMessageUserImageWrap.$( - SELECTORS.PINNED_MESSAGE_USER_IMAGE + SELECTORS.PINNED_MESSAGE_USER_IMAGE, ); } get pinnedMessageUserImageProfile() { return this.pinnedMessageUserImage.$( - SELECTORS.PINNED_MESSAGE_USER_IMAGE_PROFILE + SELECTORS.PINNED_MESSAGE_USER_IMAGE_PROFILE, ); } @@ -243,80 +243,80 @@ export default class PinnedMessages extends UplinkMainScreen { async getPinnedMessageAttachment( orderPinned: number, - attachmentNumber: number + attachmentNumber: number, ) { const pinnedContainerByIndex = await this.getPinnedMessageLocatorByAdditionOrder(orderPinned); const attachmentOnPinnedMessage = await pinnedContainerByIndex.$$( - SELECTORS.PINNED_MESSAGE_ATTACHMENTS + SELECTORS.PINNED_MESSAGE_ATTACHMENTS, )[attachmentNumber]; return attachmentOnPinnedMessage; } async getPinnedMessageAttachmentFileEmbed( orderPinned: number, - attachmentNumber: number + attachmentNumber: number, ) { const attachmentOnPinnedMessage = await this.getPinnedMessageAttachment( orderPinned, - attachmentNumber + attachmentNumber, ); const attachmentFileEmbed = await attachmentOnPinnedMessage.$( - SELECTORS.PINNED_MESSAGE_ATTACHMENTS_FILE_EMBED + SELECTORS.PINNED_MESSAGE_ATTACHMENTS_FILE_EMBED, ); return attachmentFileEmbed; } async getPinnedMessageAttachmentFileIcon( orderPinned: number, - attachmentNumber: number + attachmentNumber: number, ) { const attachmentOnPinnedFileEmbed = await this.getPinnedMessageAttachmentFileEmbed( orderPinned, - attachmentNumber + attachmentNumber, ); const attachmentFileIcon = await attachmentOnPinnedFileEmbed.$( - SELECTORS.PINNED_MESSAGE_ATTACHMENTS_FILE_ICON + SELECTORS.PINNED_MESSAGE_ATTACHMENTS_FILE_ICON, ); return attachmentFileIcon; } async getPinnedMessageAttachmentFileIconExtension( orderPinned: number, - attachmentNumber: number + attachmentNumber: number, ) { const attachmentFileIcon = await this.getPinnedMessageAttachmentFileIcon( orderPinned, - attachmentNumber + attachmentNumber, ); const attachmentFileIconExtension = await attachmentFileIcon.$( - SELECTORS.PINNED_MESSAGE_ATTACHMENTS_FILE_ICON_EXTENSION + SELECTORS.PINNED_MESSAGE_ATTACHMENTS_FILE_ICON_EXTENSION, ); return attachmentFileIconExtension; } async getPinnedMessageAttachmentFileInfo( orderPinned: number, - attachmentNumber: number + attachmentNumber: number, ) { const attachmentFileEmbed = await this.getPinnedMessageAttachmentFileEmbed( orderPinned, - attachmentNumber + attachmentNumber, ); const attachmentFileInfo = await attachmentFileEmbed.$( - SELECTORS.PINNED_MESSAGE_ATTACHMENTS_FILE_INFO + SELECTORS.PINNED_MESSAGE_ATTACHMENTS_FILE_INFO, ); return attachmentFileInfo; } async getPinnedMessageAttachmentFileMetaText( orderPinned: number, - attachmentNumber: number + attachmentNumber: number, ) { const attachmentFileInfo = await this.getPinnedMessageAttachmentFileInfo( orderPinned, - attachmentNumber + attachmentNumber, ); const fileMetaText = await attachmentFileInfo .$(SELECTORS.PINNED_MESSAGE_ATTACHMENTS_FILE_META) @@ -326,11 +326,11 @@ export default class PinnedMessages extends UplinkMainScreen { async getPinnedMessageAttachmentFileNameText( orderPinned: number, - attachmentNumber: number + attachmentNumber: number, ) { const attachmentFileInfo = await this.getPinnedMessageAttachmentFileInfo( orderPinned, - attachmentNumber + attachmentNumber, ); const fileNameText = await attachmentFileInfo .$(SELECTORS.PINNED_MESSAGE_ATTACHMENTS_FILE_NAME) @@ -342,7 +342,7 @@ export default class PinnedMessages extends UplinkMainScreen { const pinnedContainerByIndex = await this.getPinnedMessageLocatorByAdditionOrder(orderPinned); const goToButton = await pinnedContainerByIndex.$( - SELECTORS.PINNED_MESSAGE_BUTTON_GO_TO + SELECTORS.PINNED_MESSAGE_BUTTON_GO_TO, ); return goToButton; } @@ -351,7 +351,7 @@ export default class PinnedMessages extends UplinkMainScreen { const pinnedContainerByIndex = await this.getPinnedMessageLocatorByAdditionOrder(orderPinned); const unpinButton = await pinnedContainerByIndex.$( - SELECTORS.PINNED_MESSAGE_BUTTON_UNPIN + SELECTORS.PINNED_MESSAGE_BUTTON_UNPIN, ); return unpinButton; } @@ -378,7 +378,7 @@ export default class PinnedMessages extends UplinkMainScreen { const pinnedWrapByIndex = await this.getPinnedMessageWrapLocatorByAdditionOrder(orderPinned); const userImage = await pinnedWrapByIndex.$( - SELECTORS.PINNED_MESSAGE_USER_IMAGE + SELECTORS.PINNED_MESSAGE_USER_IMAGE, ); return userImage; } @@ -387,7 +387,7 @@ export default class PinnedMessages extends UplinkMainScreen { const pinnedWrapByIndex = await this.getPinnedMessageWrapLocatorByAdditionOrder(orderPinned); const userImageProfile = await pinnedWrapByIndex.$( - SELECTORS.PINNED_MESSAGE_USER_IMAGE_PROFILE + SELECTORS.PINNED_MESSAGE_USER_IMAGE_PROFILE, ); return userImageProfile; } @@ -411,13 +411,13 @@ export default class PinnedMessages extends UplinkMainScreen { return await pinnedMessagesMain.waitForDisplayed(); } - async validateFirstPinnedMessageAttachmentFileIcon() { + async validateFirstPinnedMessageAttachmentFileIcon(timeout: number = 15000) { const attachmentIcon = await this.getPinnedMessageAttachmentFileIcon(0, 0); - await attachmentIcon.waitForExist(); + await attachmentIcon.waitForExist({ timeout: timeout }); } async validateFirstPinnedMessageAttachmentFileIconExtension( - extension: string + extension: string, ) { const attachmentExtension = await this.getPinnedMessageAttachmentFileIconExtension(0, 0); @@ -434,9 +434,9 @@ export default class PinnedMessages extends UplinkMainScreen { await expect(currentName).toHaveTextContaining(expectedName); } - async validateFirstPinnedMessageImageProfileIsShown() { + async validateFirstPinnedMessageImageProfileIsShown(timeout: number = 15000) { const imageProfile = await this.getPinnedMessageUserImageProfile(0); - await imageProfile.waitForExist(); + await imageProfile.waitForExist({ timeout: timeout }); } async validateFirstPinnedMessageSender(username: string) { @@ -452,7 +452,7 @@ export default class PinnedMessages extends UplinkMainScreen { async validateFirstPinnedMessageTimestampIsShown() { const timestamp = await this.getPinnedMessageTimestampText(0); await expect(timestamp).toHaveTextContaining( - /^(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[0-2])\/\d{4}\s+(0[1-9]|1[0-2]):([0-5][0-9])\s+(AM|PM)$/ + /^(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[0-2])\/\d{4}\s+(0[1-9]|1[0-2]):([0-5][0-9])\s+(AM|PM)$/, ); } } diff --git a/tests/screenobjects/chats/ReplyPrompt.ts b/tests/screenobjects/chats/ReplyPrompt.ts index 2c32bf77414..59058d4b95a 100644 --- a/tests/screenobjects/chats/ReplyPrompt.ts +++ b/tests/screenobjects/chats/ReplyPrompt.ts @@ -142,25 +142,27 @@ export default class ReplyPrompt extends UplinkMainScreen { await replyPopUpCloseButton.click(); } - async validateReplyPromptElementsShown(message: string) { + async validateReplyPromptElementsShown( + message: string, + timeout: number = 15000, + ) { const replyPopUp = await this.replyPopUp; const replyPopUpCloseButton = await this.replyPopUpCloseButton; const replyPopUpUserImage = await this.replyPopUpUserImage; const replyPopUpIndicator = await this.replyPopUpIndicator; - await replyPopUp.waitForExist(); - await replyPopUpCloseButton.waitForExist(); - await replyPopUpUserImage.waitForExist(); - await replyPopUpIndicator.waitForExist(); + await replyPopUp.waitForExist({ timeout: timeout }); + await replyPopUpCloseButton.waitForExist({ timeout: timeout }); + await replyPopUpUserImage.waitForExist({ timeout: timeout }); + await replyPopUpIndicator.waitForExist({ timeout: timeout }); await driver[this.executor].waitUntil( async () => { return (await this.replyPopUpHeader.getText()) === "REPLYING TO:"; }, { - timeout: 15000, - timeoutMsg: - "Expected reply prompt header was incorrect after 15 seconds", - } + timeout: timeout, + timeoutMsg: "Expected reply prompt header was incorrect", + }, ); await driver[this.executor].waitUntil( @@ -170,10 +172,9 @@ export default class ReplyPrompt extends UplinkMainScreen { ); }, { - timeout: 15000, - timeoutMsg: - "Expected reply prompt header text to reply was incorrect after 15 seconds", - } + timeout: timeout, + timeoutMsg: "Expected reply prompt header text to reply was incorrect", + }, ); } @@ -185,7 +186,7 @@ export default class ReplyPrompt extends UplinkMainScreen { { timeout: 15000, timeoutMsg: "Expected reply modal is still visible after 15 seconds", - } + }, ); } } diff --git a/tests/screenobjects/chats/SendFiles.ts b/tests/screenobjects/chats/SendFiles.ts index 0fb3cd18059..d701f4265a7 100644 --- a/tests/screenobjects/chats/SendFiles.ts +++ b/tests/screenobjects/chats/SendFiles.ts @@ -218,15 +218,15 @@ export default class SendFiles extends UplinkMainScreen { return result.toString(); } - async typeOnFileNameInput(name: string) { + async typeOnFileNameInput(name: string, timeout: number = 15000) { const inputFileName = await this.inputFileName; - await inputFileName.waitForExist(); + await inputFileName.waitForExist({ timeout: timeout }); await inputFileName.setValue(name); } - async typeOnFolderNameInput(name: string) { + async typeOnFolderNameInput(name: string, timeout: number = 15000) { const inputFolderName = await this.inputFolderName; - await inputFolderName.waitForExist(); + await inputFolderName.waitForExist({ timeout: timeout }); await inputFolderName.setValue(name); } @@ -234,7 +234,7 @@ export default class SendFiles extends UplinkMainScreen { const folders = await this.filesCrumb; const treeLength = folders.length - 1; const currentFolderName = await folders[treeLength].$( - SELECTORS.FILES_CRUMB_TEXT + SELECTORS.FILES_CRUMB_TEXT, ); const currentFolderNameText = await currentFolderName.getText(); return currentFolderNameText; @@ -270,28 +270,32 @@ export default class SendFiles extends UplinkMainScreen { return locator; } - async updateNameFile(newName: string, extension: string = "") { + async updateNameFile( + newName: string, + extension: string = "", + timeout: number = 15000, + ) { const inputFileName = await this.inputFileName; - await inputFileName.waitForExist(); + await inputFileName.waitForExist({ timeout: timeout }); await inputFileName.setValue(newName); const newFile = await this.getLocatorOfFolderFile(newName + extension); const newFileElement = await this.instance.$(newFile); - await newFileElement.waitForExist(); + await newFileElement.waitForExist({ timeout: timeout }); } - async updateNameFolder(newName: string) { + async updateNameFolder(newName: string, timeout: number = 15000) { const inputFolderName = await this.inputFolderName; - await inputFolderName.waitForExist(); + await inputFolderName.waitForExist({ timeout: timeout }); await inputFolderName.setValue(newName); const newFolder = await this.getLocatorOfFolderFile(newName); const newFolderElement = await this.instance.$(newFolder); - await newFolderElement.waitForExist(); + await newFolderElement.waitForExist({ timeout: timeout }); } - async validateFileOrFolderExist(locator: string) { + async validateFileOrFolderExist(locator: string, timeout: number = 15000) { const fileFolderElementLocator = await this.getLocatorOfFolderFile(locator); const fileFolderElement = await this.instance.$(fileFolderElementLocator); - await fileFolderElement.waitForExist(); + await fileFolderElement.waitForExist({ timeout: timeout }); } async validateFileOrFolderNotExist(locator: string) { @@ -299,9 +303,9 @@ export default class SendFiles extends UplinkMainScreen { await this.instance.$(fileFolderLocator).waitForExist({ reverse: true }); } - async validateNoFilesAvailableIsShown() { + async validateNoFilesAvailableIsShown(timeout: number = 15000) { const noFilesAvailable = await this.noFilesAvailable; - await noFilesAvailable.waitForExist(); + await noFilesAvailable.waitForExist({ timeout: timeout }); await expect(noFilesAvailable).toHaveTextContaining("NO FILES AVAILABLE."); } @@ -311,21 +315,21 @@ export default class SendFiles extends UplinkMainScreen { }); } - async validateSendFilesModalIsShown() { + async validateSendFilesModalIsShown(timeout: number = 15000) { const filesBody = await this.sendFilesLayout; - await filesBody.waitForExist(); + await filesBody.waitForExist({ timeout: timeout }); } - async validateThumbnailIsShown(name: string) { + async validateThumbnailIsShown(name: string, timeout: number = 15000) { const fileElementLocator = await this.getLocatorOfFolderFile(name); const fileElement = await this.instance.$(fileElementLocator); const fileThumbnail = await fileElement.$(SELECTORS.FILE_THUMBNAIL); - await fileThumbnail.waitForExist(); + await fileThumbnail.waitForExist({ timeout: timeout }); } // Context Menu methods - async openFilesContextMenu(name: string) { + async openFilesContextMenu(name: string, timeout: number = 15000) { const elementLocator = await this.getLocatorOfFolderFile(name); const fileFolderToRightClick = await this.instance .$(elementLocator) @@ -336,7 +340,7 @@ export default class SendFiles extends UplinkMainScreen { } else if (currentDriver === WINDOWS_DRIVER) { await rightClickOnWindows(fileFolderToRightClick, this.executor); } - await this.contextMenu.waitForExist(); + await this.contextMenu.waitForExist({ timeout: timeout }); } async clickOnFilesRename() { diff --git a/tests/screenobjects/chats/Topbar.ts b/tests/screenobjects/chats/Topbar.ts index 2428227967c..ff60a1c094c 100644 --- a/tests/screenobjects/chats/Topbar.ts +++ b/tests/screenobjects/chats/Topbar.ts @@ -223,18 +223,19 @@ export default class Topbar extends UplinkMainScreen { // Top Bar Methods - async addToFavorites() { + async addToFavorites(timeout: number = 15000) { const topbarAddToFavorites = await this.topbarAddToFavorites; await this.hoverOnElement(topbarAddToFavorites); await topbarAddToFavorites.click(); await driver[this.executor].waitUntil( async () => { - return await this.topbarRemoveFromFavorites.waitForExist(); + return await this.topbarRemoveFromFavorites.waitForExist({ + timeout: timeout, + }); }, { - timeout: 15000, - timeoutMsg: - "Remove from favorites button was not displayed after passing 15 seconds from adding the same user of favorites", + timeout: timeout, + timeoutMsg: "Remove from favorites button was not displayed again", }, ); } @@ -292,15 +293,17 @@ export default class Topbar extends UplinkMainScreen { await topbarRemoveFromFavorites.click(); } - async validateTopbarIndicatorOnline() { + async validateTopbarIndicatorOnline(timeout: number = 15000) { await driver[this.executor].waitUntil( async () => { - return await this.topbarIndicatorOnline.waitForExist(); + return await this.topbarIndicatorOnline.waitForExist({ + timeout: timeout, + }); }, { - timeout: 60000, + timeout: timeout, timeoutMsg: - "Expected indicator online was never displayed on Chat Screen topbar after 60 seconds", + "Expected indicator online was never displayed on Chat Screen topbar", }, ); } @@ -318,10 +321,10 @@ export default class Topbar extends UplinkMainScreen { ); } - async validateTopbarUserImage() { + async validateTopbarUserImage(timeout: number = 15000) { await driver[this.executor].waitUntil( async () => { - return await this.topbarUserImage.waitForExist(); + return await this.topbarUserImage.waitForExist({ timeout: timeout }); }, { timeout: 15000, @@ -331,10 +334,10 @@ export default class Topbar extends UplinkMainScreen { ); } - async validateTopbarExists() { + async validateTopbarExists(timeout: number = 15000) { await driver[this.executor].waitUntil( async () => { - return await this.topbar.waitForExist(); + return await this.topbar.waitForExist({ timeout: timeout }); }, { timeout: 15000, @@ -343,14 +346,16 @@ export default class Topbar extends UplinkMainScreen { ); } - async waitUntilRemoteUserIsOnline() { + async waitUntilRemoteUserIsOnline(timeout: number = 60000) { await driver[this.executor].waitUntil( async () => { - return await this.topbarIndicatorOnline.waitForExist(); + return await this.topbarIndicatorOnline.waitForExist({ + timeout: timeout, + }); }, { - timeout: 60000, - timeoutMsg: "Remote user never shown as online after 60 seconds", + timeout: timeout, + timeoutMsg: "Remote user never shown as online", }, ); } diff --git a/tests/screenobjects/files/FilesScreen.ts b/tests/screenobjects/files/FilesScreen.ts index a2da3a5d456..46317d5cae2 100644 --- a/tests/screenobjects/files/FilesScreen.ts +++ b/tests/screenobjects/files/FilesScreen.ts @@ -372,7 +372,7 @@ export default class FilesScreen extends UplinkMainScreen { } } - async createFolder(name: string) { + async createFolder(name: string, timeout: number = 15000) { await this.clickOnCreateFolder(); const inputFolderName = await this.inputFolderName; const filesInfoCurrentSizeLabel = await this.filesInfoCurrentSizeLabel; @@ -386,7 +386,7 @@ export default class FilesScreen extends UplinkMainScreen { await filesInfoCurrentSizeLabel.click(); const newFolder = await this.getLocatorOfFolderFile(name); const newFolderElement = await this.instance.$(newFolder); - await newFolderElement.waitForExist(); + await newFolderElement.waitForExist({ timeout: timeout }); } async typeOnFileNameInput(name: string) { @@ -489,26 +489,30 @@ export default class FilesScreen extends UplinkMainScreen { return progressText; } - async updateNameFile(newName: string, extension: string = "") { + async updateNameFile( + newName: string, + extension: string = "", + timeout: number = 15000, + ) { const inputFileName = await this.inputFileName; - await inputFileName.waitForExist(); + await inputFileName.waitForExist({ timeout: timeout }); await inputFileName.setValue(newName); const filesInfoCurrentSizeLabel = await this.filesInfoCurrentSizeLabel; await filesInfoCurrentSizeLabel.click(); const newFile = await this.getLocatorOfFolderFile(newName + extension); const newFileElement = await this.instance.$(newFile); - await newFileElement.waitForExist(); + await newFileElement.waitForExist({ timeout: timeout }); } - async updateNameFolder(newName: string) { + async updateNameFolder(newName: string, timeout: number = 15000) { const inputFolderName = await this.inputFolderName; - await inputFolderName.waitForExist(); + await inputFolderName.waitForExist({ timeout: timeout }); await inputFolderName.setValue(newName); const filesInfoCurrentSizeLabel = await this.filesInfoCurrentSizeLabel; await filesInfoCurrentSizeLabel.click(); const newFolder = await this.getLocatorOfFolderFile(newName); const newFolderElement = await this.instance.$(newFolder); - await newFolderElement.waitForExist(); + await newFolderElement.waitForExist({ timeout: timeout }); } async uploadFile(relativePath: string) { @@ -535,9 +539,9 @@ export default class FilesScreen extends UplinkMainScreen { await this.instance.$(fileFolderLocator).waitForExist({ reverse: true }); } - async validateFilesScreenIsShown() { + async validateFilesScreenIsShown(timeout: number = 15000) { const filesBody = await this.filesBody; - await filesBody.waitForExist(); + await filesBody.waitForExist({ timeout: timeout }); } // Hovering methods @@ -554,7 +558,7 @@ export default class FilesScreen extends UplinkMainScreen { // Context Menu methods - async openFilesContextMenu(name: string) { + async openFilesContextMenu(name: string, timeout: number = 15000) { const elementLocator = await this.getLocatorOfFolderFile(name); const fileFolderToRightClick = await this.instance .$(elementLocator) @@ -565,7 +569,7 @@ export default class FilesScreen extends UplinkMainScreen { } else if (currentDriver === WINDOWS_DRIVER) { await rightClickOnWindows(fileFolderToRightClick, this.executor); } - await this.contextMenu.waitForExist(); + await this.contextMenu.waitForExist({ timeout: timeout }); } async clickOnFilesDelete() { diff --git a/tests/screenobjects/friends/FriendsScreen.ts b/tests/screenobjects/friends/FriendsScreen.ts index d435cdf2337..c5917fc0c20 100644 --- a/tests/screenobjects/friends/FriendsScreen.ts +++ b/tests/screenobjects/friends/FriendsScreen.ts @@ -439,9 +439,9 @@ export default class FriendsScreen extends UplinkMainScreen { return abbreviated; } - async getAllFriendsList() { + async getAllFriendsList(timeout: number = 15000) { const friendsList = await this.friendsList; - await friendsList.waitForExist(); + await friendsList.waitForExist({ timeout: timeout }); const friends = await this.instance.$$(SELECTORS.FRIEND_INFO_USERNAME); let results = []; for (let friend of friends) { @@ -452,9 +452,9 @@ export default class FriendsScreen extends UplinkMainScreen { return results; } - async getBlockedList() { + async getBlockedList(timeout: number = 15000) { const blockedList = await this.blockedList; - await blockedList.waitForExist(); + await blockedList.waitForExist({ timeout: timeout }); const friends = await this.instance.$$(SELECTORS.FRIEND_INFO_USERNAME); let results = []; for (let friend of friends) { @@ -465,7 +465,10 @@ export default class FriendsScreen extends UplinkMainScreen { return results; } - async getExistingFriendByAriaLabel(username: string) { + async getExistingFriendByAriaLabel( + username: string, + timeout: number = 15000, + ) { const currentDriver = await this.getCurrentDriver(); let locator; if (currentDriver === MACOS_DRIVER) { @@ -475,7 +478,7 @@ export default class FriendsScreen extends UplinkMainScreen { .$(SELECTORS.FRIENDS_BODY) .$('[name="' + username + '"]'); } - await locator.waitForExist(); + await locator.waitForExist({ timeout: timeout }); return locator; } @@ -490,9 +493,9 @@ export default class FriendsScreen extends UplinkMainScreen { return locator; } - async getIncomingList() { + async getIncomingList(timeout: number = 15000) { const incomingList = await this.incomingRequestsList; - await incomingList.waitForExist(); + await incomingList.waitForExist({ timeout: timeout }); const friends = await this.instance .$(SELECTORS.INCOMING_REQUESTS_LIST) .$$(SELECTORS.FRIEND_INFO_USERNAME); @@ -511,9 +514,9 @@ export default class FriendsScreen extends UplinkMainScreen { return errorText; } - async getOutgoingList() { + async getOutgoingList(timeout: number = 15000) { const outgoingList = await this.outgoingRequestsList; - await outgoingList.waitForExist(); + await outgoingList.waitForExist({ timeout: timeout }); const friends = await this.instance .$(SELECTORS.OUTGOING_REQUESTS_LIST) .$$(SELECTORS.FRIEND_INFO_USERNAME); @@ -526,9 +529,9 @@ export default class FriendsScreen extends UplinkMainScreen { return results; } - async getUserFromAllFriendsList() { + async getUserFromAllFriendsList(timeout: number = 15000) { const friendsList = await this.friendsList; - await friendsList.waitForExist(); + await friendsList.waitForExist({ timeout: timeout }); const firstUserFromList = await this.instance .$$(SELECTORS.FRIEND_INFO_USERNAME)[0] .$(SELECTORS.FRIEND_INFO_USERNAME_NAME); @@ -536,9 +539,9 @@ export default class FriendsScreen extends UplinkMainScreen { return firstUserFromListText; } - async getUserFromIncomingList() { + async getUserFromIncomingList(timeout: number = 15000) { const incomingList = await this.incomingRequestsList; - await incomingList.waitForExist(); + await incomingList.waitForExist({ timeout: timeout }); const firstUserFromList = await this.instance .$(SELECTORS.INCOMING_REQUESTS_LIST) .$$(SELECTORS.FRIEND_INFO_USERNAME)[0] @@ -547,9 +550,9 @@ export default class FriendsScreen extends UplinkMainScreen { return firstUserFromListText; } - async getUserFromOutgoingList() { + async getUserFromOutgoingList(timeout: number = 15000) { const outgoingList = await this.outgoingRequestsList; - await outgoingList.waitForExist(); + await outgoingList.waitForExist({ timeout: timeout }); const firstUserFromList = await this.instance .$(SELECTORS.OUTGOING_REQUESTS_LIST) .$$(SELECTORS.FRIEND_INFO_USERNAME)[0] @@ -558,9 +561,9 @@ export default class FriendsScreen extends UplinkMainScreen { return firstUserFromListText; } - async getUserFromBlockedList() { + async getUserFromBlockedList(timeout: number = 15000) { const blockedList = await this.blockedList; - await blockedList.waitForExist(); + await blockedList.waitForExist({ timeout: timeout }); const firstUserFromList = await this.instance .$$(SELECTORS.FRIEND_INFO_USERNAME)[0] .$(SELECTORS.FRIEND_INFO_USERNAME_NAME); @@ -568,57 +571,57 @@ export default class FriendsScreen extends UplinkMainScreen { return firstUserFromListText; } - async getUserImage(username: string) { + async getUserImage(username: string, timeout: number = 15000) { const userLocator = await this.getExistingFriendByAriaLabel(username); const userImage = await userLocator.$(SELECTORS.FRIEND_USER_IMAGE); - await userImage.waitForExist(); + await userImage.waitForExist({ timeout: timeout }); return userImage; } - async getUserImageProfile(username: string) { + async getUserImageProfile(username: string, timeout: number = 15000) { const userLocator = await this.getExistingFriendByAriaLabel(username); const userImageProfile = await userLocator.$( SELECTORS.FRIEND_USER_IMAGE_PROFILE, ); - await userImageProfile.waitForExist(); + await userImageProfile.waitForExist({ timeout: timeout }); return userImageProfile; } - async getUserImageWrap(username: string) { + async getUserImageWrap(username: string, timeout: number = 15000) { const userLocator = await this.getExistingFriendByAriaLabel(username); const userImageWrap = await userLocator.$(SELECTORS.FRIEND_USER_IMAGE_WRAP); - await userImageWrap.waitForExist(); + await userImageWrap.waitForExist({ timeout: timeout }); return userImageWrap; } - async getUserIndicator(username: string) { + async getUserIndicator(username: string, timeout: number = 15000) { const userLocator = await this.getExistingFriendByAriaLabel(username); const indicator = await userLocator.$(SELECTORS.FRIEND_USER_INDICATOR); - await indicator.waitForExist(); + await indicator.waitForExist({ timeout: timeout }); return indicator; } - async getUserIndicatorOffline(username: string) { + async getUserIndicatorOffline(username: string, timeout: number = 15000) { const userLocator = await this.getExistingFriendByAriaLabel(username); const indicatorOffline = await userLocator.$( SELECTORS.FRIEND_USER_INDICATOR_OFFLINE, ); - await indicatorOffline.waitForExist(); + await indicatorOffline.waitForExist({ timeout: timeout }); return indicatorOffline; } - async getUserIndicatorOnline(username: string) { + async getUserIndicatorOnline(username: string, timeout: number = 15000) { const userLocator = await this.getExistingFriendByAriaLabel(username); await driver[this.executor].waitUntil( async () => { return await userLocator .$(SELECTORS.FRIEND_USER_INDICATOR_ONLINE) - .waitForExist(); + .waitForExist({ timeout: timeout }); }, { - timeout: 60000, + timeout: timeout, timeoutMsg: - "Expected indicator online was never displayed on Friends Screen User after 60 seconds", + "Expected indicator online was never displayed on Friends Screen User", }, ); const indicatorOnline = await userLocator.$( @@ -633,12 +636,12 @@ export default class FriendsScreen extends UplinkMainScreen { return userTooltip; } - async getUserTooltipText(username: string) { + async getUserTooltipText(username: string, timeout: number = 15000) { const userLocator = await this.getExistingFriendByAriaLabel(username); const userTooltipText = await userLocator .$(SELECTORS.TOOLTIP) .$(SELECTORS.TOOLTIP_TEXT); - await userTooltipText.waitForExist(); + await userTooltipText.waitForExist({ timeout: timeout }); return userTooltipText; } @@ -721,90 +724,90 @@ export default class FriendsScreen extends UplinkMainScreen { await removeOrDenyButton.click(); } - async validateAllFriendsListIsNotEmpty() { + async validateAllFriendsListIsNotEmpty(timeout: number = 60000) { // Wait until friends list is not empty await driver[this.executor].waitUntil( async () => { return await this.instance .$(SELECTORS.FRIENDS_LIST) .$(SELECTORS.FRIEND_INFO_USERNAME) - .waitForExist(); + .waitForExist({ timeout: timeout }); }, { - timeout: 60000, - timeoutMsg: "All friends list never shown any records after 60 seconds", + timeout: timeout, + timeoutMsg: "All friends list never shown any records", }, ); } - async validateAllFriendsListIsShown() { + async validateAllFriendsListIsShown(timeout: number = 15000) { const allFriendsList = await this.friendsList; - await allFriendsList.waitForExist(); + await allFriendsList.waitForExist({ timeout: timeout }); } - async validateBlockedListIsNotEmpty() { + async validateBlockedListIsNotEmpty(timeout: number = 60000) { // Wait until blocked list is not empty await driver[this.executor].waitUntil( async () => { return await this.instance .$(SELECTORS.BLOCKED_LIST) .$(SELECTORS.FRIEND_INFO_USERNAME) - .waitForExist(); + .waitForExist({ timeout: timeout }); }, { - timeout: 60000, - timeoutMsg: - "Blocked friends list never shown any records after 60 seconds", + timeout: timeout, + timeoutMsg: "Blocked friends list never shown any records", }, ); } - async validateBlockedListIsShown() { + async validateBlockedListIsShown(timeout: number = 15000) { const blockedList = await this.blockedList; - await blockedList.waitForExist(); + await blockedList.waitForExist({ timeout: timeout }); } - async validateChatWithFriendButtonIsShown() { + async validateChatWithFriendButtonIsShown(timeout: number = 15000) { const chatWithFriend = await this.chatWithFriendButton; - await chatWithFriend.waitForExist(); + await chatWithFriend.waitForExist({ timeout: timeout }); } - async validateChatWithFriendButtonExists() { + async validateChatWithFriendButtonExists(timeout: number = 60000) { // Wait until incoming list is not empty await driver[this.executor].waitUntil( async () => { - return await this.chatWithFriendButton.waitForExist(); + return await this.chatWithFriendButton.waitForExist({ + timeout: timeout, + }); }, { - timeout: 60000, - timeoutMsg: "Chat with friend button does not exist after 60 seconds", + timeout: timeout, + timeoutMsg: "Chat with friend button does not exist", }, ); } - async validateFriendsButtonBadgeIsShown() { + async validateFriendsButtonBadgeIsShown(timeout: number = 15000) { const friendsButtonBadge = await this.friendsButtonBadge; - await friendsButtonBadge.waitForExist(); + await friendsButtonBadge.waitForExist({ timeout: timeout }); } - async validateFriendsScreenIsShown() { + async validateFriendsScreenIsShown(timeout: number = 15000) { const friendsScreen = await this.friendsBody; - await friendsScreen.waitForExist(); + await friendsScreen.waitForExist({ timeout: timeout }); } - async validateIncomingListIsNotEmpty() { + async validateIncomingListIsNotEmpty(timeout: number = 60000) { // Wait until incoming list is not empty await driver[this.executor].waitUntil( async () => { return await this.instance .$(SELECTORS.INCOMING_REQUESTS_LIST) .$(SELECTORS.FRIEND_INFO_USERNAME) - .waitForExist(); + .waitForExist({ timeout: timeout }); }, { - timeout: 60000, - timeoutMsg: - "Incoming friends list never shown any records after 60 seconds", + timeout: timeout, + timeoutMsg: "Incoming friends list never shown any records", }, ); } @@ -815,41 +818,40 @@ export default class FriendsScreen extends UplinkMainScreen { }); } - async validateIncomingListIsShown() { + async validateIncomingListIsShown(timeout: number = 15000) { const incomingList = await this.incomingRequestsList; - await incomingList.waitForExist(); + await incomingList.waitForExist({ timeout: timeout }); } - async validateNoRequestsIsShown() { + async validateNoRequestsIsShown(timeout: number = 15000) { // Ensure no requests message is displayed const noRequests = await this.noRequests; - await noRequests.waitForExist(); + await noRequests.waitForExist({ timeout: timeout }); } - async validateOutgoingListIsNotEmpty() { + async validateOutgoingListIsNotEmpty(timeout: number = 60000) { await driver[this.executor].waitUntil( async () => { return await this.instance .$(SELECTORS.OUTGOING_REQUESTS_LIST) .$(SELECTORS.FRIEND_INFO_USERNAME) - .waitForExist(); + .waitForExist({ timeout: timeout }); }, { - timeout: 60000, - timeoutMsg: - "Expected friend list never shown any records after 60 seconds", + timeout: timeout, + timeoutMsg: "Expected friend list never shown any records", }, ); } - async validateOutgoingListIsShown() { + async validateOutgoingListIsShown(timeout: number = 15000) { const outgoingList = await this.outgoingRequestsList; - await outgoingList.waitForExist(); + await outgoingList.waitForExist({ timeout: timeout }); } - async validateRemoveOrDenyButtonIsShown() { + async validateRemoveOrDenyButtonIsShown(timeout: number = 15000) { const removeOrDenyButton = await this.removeOrDenyFriendButton; - await removeOrDenyButton.waitForExist(); + await removeOrDenyButton.waitForExist({ timeout: timeout }); } async waitUntilFriendIsRemoved( @@ -864,42 +866,50 @@ export default class FriendsScreen extends UplinkMainScreen { .waitForExist({ timeout: timeoutUser, reverse: true }); } - async waitUntilFriendRequestIsReceived() { + async waitUntilFriendRequestIsReceived(timeout: number = 180000) { await driver[this.executor].waitUntil( async () => { - return await this.acceptFriendRequestButton.waitForExist(); + return await this.acceptFriendRequestButton.waitForExist({ + timeout: timeout, + }); }, { - timeout: 240000, + timeout: timeout, timeoutMsg: - "Expected Accept Friend Request button was never displayed on Friends Screen after 4 minutes", + "Expected Accept Friend Request button was never displayed on Friends Screen", }, ); } - async waitUntilUserAcceptedFriendRequest() { + async waitUntilUserAcceptedFriendRequest(timeout: number = 180000) { await driver[this.executor].waitUntil( async () => { - return await this.chatWithFriendButton.waitForExist(); + return await this.chatWithFriendButton.waitForExist({ + timeout: timeout, + }); }, { - timeout: 240000, + timeout: timeout, timeoutMsg: - "Expected Chat With Friend button was never displayed on Friends Screen after 4 minutes", + "Expected Chat With Friend button was never displayed on Friends Screen", }, ); } - async waitUntilUserIsInCurrentList(username: string) { + async waitUntilUserIsInCurrentList( + username: string, + timeout: number = 15000, + ) { const user = await this.getExistingFriendByAriaLabel(username); await driver[this.executor].waitUntil( async () => { - return await user.$(SELECTORS.FRIEND_INFO_USERNAME).waitForExist(); + return await user + .$(SELECTORS.FRIEND_INFO_USERNAME) + .waitForExist({ timeout: timeout }); }, { - timeout: 60000, - timeoutMsg: - "Expected Username was never displayed on Friends Screen after 60 seconds", + timeout: timeout, + timeoutMsg: "Expected Username was never displayed on Friends Screen", }, ); } @@ -951,7 +961,7 @@ export default class FriendsScreen extends UplinkMainScreen { await contextMenuUnblock.click(); } - async openFriendContextMenu(name: string) { + async openFriendContextMenu(name: string, timeout: number = 15000) { const friendElement = await this.getExistingFriendByAriaLabel(name); const currentDriver = await this.getCurrentDriver(); if (currentDriver === MACOS_DRIVER) { @@ -960,6 +970,6 @@ export default class FriendsScreen extends UplinkMainScreen { await rightClickOnWindows(friendElement, this.executor); } const contextMenu = await this.contextMenu; - await contextMenu.waitForExist(); + await contextMenu.waitForExist({ timeout: timeout }); } } diff --git a/tests/screenobjects/settings/SettingsGeneralScreen.ts b/tests/screenobjects/settings/SettingsGeneralScreen.ts index 746b8075c66..7cf1baae776 100644 --- a/tests/screenobjects/settings/SettingsGeneralScreen.ts +++ b/tests/screenobjects/settings/SettingsGeneralScreen.ts @@ -432,8 +432,8 @@ export default class SettingsGeneralScreen extends SettingsBaseScreen { await this.hoverOnElement(openThemesButton); } - async validateSettingsGeneralIsShown() { + async validateSettingsGeneralIsShown(timeout: number = 15000) { const settingsGeneral = await this.settingsGeneral; - await settingsGeneral.waitForExist(); + await settingsGeneral.waitForExist({ timeout: timeout }); } } diff --git a/tests/screenobjects/settings/SettingsMessagesScreen.ts b/tests/screenobjects/settings/SettingsMessagesScreen.ts index 7f80253312a..2ed2cc09334 100644 --- a/tests/screenobjects/settings/SettingsMessagesScreen.ts +++ b/tests/screenobjects/settings/SettingsMessagesScreen.ts @@ -122,8 +122,8 @@ export default class SettingsMessagesScreen extends SettingsBaseScreen { } } - async validateSettingsMessagesIsShown() { + async validateSettingsMessagesIsShown(timeout: number = 15000) { const settingsMessages = await this.settingsMessages; - await settingsMessages.waitForExist(); + await settingsMessages.waitForExist({ timeout: timeout }); } } diff --git a/tests/screenobjects/settings/SettingsNotificationsScreen.ts b/tests/screenobjects/settings/SettingsNotificationsScreen.ts index 80974e5a9e3..a67ff76164a 100644 --- a/tests/screenobjects/settings/SettingsNotificationsScreen.ts +++ b/tests/screenobjects/settings/SettingsNotificationsScreen.ts @@ -166,8 +166,8 @@ export default class SettingsNotificationsScreen extends SettingsBaseScreen { async clickOnFriendsNotifications() { const currentDriver = await this.getCurrentDriver(); if (currentDriver === WINDOWS_DRIVER) { - const friendsNotificationsCheckbox = await this - .friendsNotificationsCheckbox; + const friendsNotificationsCheckbox = + await this.friendsNotificationsCheckbox; await friendsNotificationsCheckbox.click(); } else if (currentDriver === MACOS_DRIVER) { const locator = await this.friendsNotificationsCheckbox; @@ -178,8 +178,8 @@ export default class SettingsNotificationsScreen extends SettingsBaseScreen { async clickOnMessagesNotifications() { const currentDriver = await this.getCurrentDriver(); if (currentDriver === WINDOWS_DRIVER) { - const messagesNotificationsCheckbox = await this - .messagesNotificationsCheckbox; + const messagesNotificationsCheckbox = + await this.messagesNotificationsCheckbox; await messagesNotificationsCheckbox.click(); } else if (currentDriver === MACOS_DRIVER) { const locator = await this.messagesNotificationsCheckbox; @@ -190,8 +190,8 @@ export default class SettingsNotificationsScreen extends SettingsBaseScreen { async clickOnSettingsNotifications() { const currentDriver = await this.getCurrentDriver(); if (currentDriver === WINDOWS_DRIVER) { - const settingsNotificationsCheckbox = await this - .settingsNotificationsCheckbox; + const settingsNotificationsCheckbox = + await this.settingsNotificationsCheckbox; await settingsNotificationsCheckbox.click(); } else if (currentDriver === MACOS_DRIVER) { const locator = await this.settingsNotificationsCheckbox; @@ -199,8 +199,8 @@ export default class SettingsNotificationsScreen extends SettingsBaseScreen { } } - async validateSettingsNotificationsIsShown() { + async validateSettingsNotificationsIsShown(timeout: number = 15000) { const settingsNotifications = await this.settingsNotifications; - await settingsNotifications.waitForExist(); + await settingsNotifications.waitForExist({ timeout: timeout }); } } diff --git a/tests/screenobjects/settings/SettingsProfileScreen.ts b/tests/screenobjects/settings/SettingsProfileScreen.ts index 6b259081a89..f2cc5bacbbc 100644 --- a/tests/screenobjects/settings/SettingsProfileScreen.ts +++ b/tests/screenobjects/settings/SettingsProfileScreen.ts @@ -15,7 +15,7 @@ import { import SettingsBaseScreen from "@screenobjects/settings/SettingsBaseScreen"; const currentOS = driver[USER_A_INSTANCE].capabilities.automationName; -const {keyboard, Key} = require("@nut-tree/nut-js"); +const { keyboard, Key } = require("@nut-tree/nut-js"); let SELECTORS = {}; const SELECTORS_COMMON = { @@ -333,7 +333,7 @@ export default class SettingsProfileScreen extends SettingsBaseScreen { { timeout: 5000, timeoutMsg: "Expected status input to contain did:key after 5 seconds", - } + }, ); } @@ -371,20 +371,20 @@ export default class SettingsProfileScreen extends SettingsBaseScreen { } } - async validateBannerPictureIsShown() { + async validateBannerPictureIsShown(timeout: number = 15000) { // Validate that profile banner is displayed on screen const bannerImage = await this.profileBanner; - await bannerImage.waitForExist(); + await bannerImage.waitForExist({ timeout: timeout }); } - async validateProfilePictureIsShown() { + async validateProfilePictureIsShown(timeout: number = 15000) { // Validate that profile picture is displayed on screen const profilePictureImage = await this.profilePicture; - await profilePictureImage.waitForExist(); + await profilePictureImage.waitForExist({ timeout: timeout }); } - async validateSettingsProfileIsShown() { + async validateSettingsProfileIsShown(timeout: number = 15000) { const settingsProfile = await this.settingsProfile; - await settingsProfile.waitForExist(); + await settingsProfile.waitForExist({ timeout: timeout }); } } diff --git a/tests/screenobjects/welcome-screen/WelcomeScreen.ts b/tests/screenobjects/welcome-screen/WelcomeScreen.ts index 40cea7eebbc..a1bec38873f 100644 --- a/tests/screenobjects/welcome-screen/WelcomeScreen.ts +++ b/tests/screenobjects/welcome-screen/WelcomeScreen.ts @@ -53,8 +53,8 @@ export default class WelcomeScreen extends UplinkMainScreen { await addSomeoneButton.click(); } - async validateWelcomeScreenIsShown() { + async validateWelcomeScreenIsShown(timeout: number = 15000) { const welcomeLayout = await this.welcomeLayout; - await welcomeLayout.waitForExist(); + await welcomeLayout.waitForExist({ timeout: timeout }); } } From f8865c56990a6c6074fc7e1fc217580ede2fd926 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Carden=CC=83a?= <35935591+luisecm@users.noreply.github.com> Date: Tue, 7 Nov 2023 12:49:17 -0600 Subject: [PATCH 19/22] test(update): fix chat test for user A to go to incoming list --- .../reusable-accounts/ChatUserA/01-main-chats-userA.spec.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/specs/reusable-accounts/ChatUserA/01-main-chats-userA.spec.ts b/tests/specs/reusable-accounts/ChatUserA/01-main-chats-userA.spec.ts index a4838eed851..c050f990ba6 100644 --- a/tests/specs/reusable-accounts/ChatUserA/01-main-chats-userA.spec.ts +++ b/tests/specs/reusable-accounts/ChatUserA/01-main-chats-userA.spec.ts @@ -33,7 +33,6 @@ export default async function mainChatsTestsUserA() { // With User A - Go to pending requests list, wait for receiving the friend request and accept it await friendsScreenFirstUser.hoverOnPendingListButton(); await friendsScreenFirstUser.goToPendingFriendsList(); - await friendsScreenFirstUser.validateIncomingListIsShown(); await friendsScreenFirstUser.waitUntilFriendRequestIsReceived(); await friendsScreenFirstUser.acceptIncomingRequest("ChatUserB"); From eb0848ef1989f8d718d6ee95e84689a1c5c5e6fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Carden=CC=83a?= <35935591+luisecm@users.noreply.github.com> Date: Tue, 7 Nov 2023 13:56:18 -0600 Subject: [PATCH 20/22] chore(appium): update toolchain and type did method --- .github/workflows/ui-automated-tests.yml | 2 +- .github/workflows/ui-automated-windows.yml | 17 ++++++----------- tests/screenobjects/friends/FriendsScreen.ts | 5 ++++- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ui-automated-tests.yml b/.github/workflows/ui-automated-tests.yml index f4c4b335be0..017e1c1e157 100644 --- a/.github/workflows/ui-automated-tests.yml +++ b/.github/workflows/ui-automated-tests.yml @@ -30,7 +30,7 @@ jobs: - name: Install Rust ๐Ÿ’ฟ uses: actions-rs/toolchain@v1 with: - toolchain: 1.70.0 + toolchain: 1.73.0 override: true components: rustfmt, clippy diff --git a/.github/workflows/ui-automated-windows.yml b/.github/workflows/ui-automated-windows.yml index 7063ce1e822..6fb807178c0 100644 --- a/.github/workflows/ui-automated-windows.yml +++ b/.github/workflows/ui-automated-windows.yml @@ -29,7 +29,7 @@ jobs: - name: Install Rust ๐Ÿ’ฟ uses: actions-rs/toolchain@v1 with: - toolchain: 1.70.0 + toolchain: 1.73.0 override: true components: rustfmt, clippy @@ -85,7 +85,7 @@ jobs: - name: Change resolution on Windows Runner run: Set-DisplayResolution -Width 1920 -Height 1080 -Force shell: powershell - + - name: Download the Windows app ๐Ÿ—ณ๏ธ uses: actions/download-artifact@v3 with: @@ -324,7 +324,7 @@ jobs: # with: # name: test-report-macos-ci # path: artifacts - + #- name: Download Test Report for MacOS Chat A # uses: actions/download-artifact@v3 # with: @@ -335,7 +335,7 @@ jobs: # uses: actions/download-artifact@v3 # with: # name: test-report-macos-chatB - # path: artifacts + # path: artifacts - name: Download Test Report for Windows Chats uses: actions/download-artifact@v3 @@ -354,7 +354,7 @@ jobs: # with: # name: test-allure-mac-ci # path: allure - + #- name: Download Allure Results for MacOS Chat A # uses: actions/download-artifact@v3 # with: @@ -425,12 +425,7 @@ jobs: remove-artifacts: needs: - [ - build-windows, - test-windows-chats, - test-windows, - publish-test-results, - ] + [build-windows, test-windows-chats, test-windows, publish-test-results] runs-on: ubuntu-latest steps: diff --git a/tests/screenobjects/friends/FriendsScreen.ts b/tests/screenobjects/friends/FriendsScreen.ts index c5917fc0c20..11faa51e361 100644 --- a/tests/screenobjects/friends/FriendsScreen.ts +++ b/tests/screenobjects/friends/FriendsScreen.ts @@ -407,9 +407,12 @@ export default class FriendsScreen extends UplinkMainScreen { async enterFriendDidKey(didkey: string) { const addSomeoneInput = await this.addSomeoneInput; - await addSomeoneInput.click(); await addSomeoneInput.clearValue(); await addSomeoneInput.setValue(didkey); + const addSomeoneInputText = await addSomeoneInput.getText(); + if (addSomeoneInputText !== didkey) { + await this.enterFriendDidKey(didkey); + } } async enterCopiedID() { From dc0bf46154ba50f35d814a2c8aaac689cc89b1af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Carden=CC=83a?= <35935591+luisecm@users.noreply.github.com> Date: Tue, 7 Nov 2023 16:44:01 -0600 Subject: [PATCH 21/22] test(update): add validation before clicking --- .../reusable-accounts/ChatUserB/01-main-chats-userB.spec.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/specs/reusable-accounts/ChatUserB/01-main-chats-userB.spec.ts b/tests/specs/reusable-accounts/ChatUserB/01-main-chats-userB.spec.ts index cde1cc590a9..e4b205854af 100644 --- a/tests/specs/reusable-accounts/ChatUserB/01-main-chats-userB.spec.ts +++ b/tests/specs/reusable-accounts/ChatUserB/01-main-chats-userB.spec.ts @@ -25,6 +25,8 @@ export default async function mainChatsTestsUserB() { // Obtain did key from Chat User B const friendDidKey = await getUserKey("ChatUserA", USER_A_INSTANCE); await friendsScreenFirstUser.enterFriendDidKey(friendDidKey); + const addSomeoneInput = await friendsScreenFirstUser.addSomeoneInput; + await expect(addSomeoneInput).toHaveTextContaining(friendDidKey); await friendsScreenFirstUser.clickOnAddSomeoneButton(); // Wait for toast notification to be closed From 17b37965418c7bacc48ba6252fda6c1ac3e152dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Carden=CC=83a?= <35935591+luisecm@users.noreply.github.com> Date: Tue, 7 Nov 2023 16:47:49 -0600 Subject: [PATCH 22/22] chore(appium): fixing conflicts --- .github/workflows/ui-automated-tests.yml | 60 +--------------------- .github/workflows/ui-automated-windows.yml | 2 +- 2 files changed, 2 insertions(+), 60 deletions(-) diff --git a/.github/workflows/ui-automated-tests.yml b/.github/workflows/ui-automated-tests.yml index a2a6f9b5371..53bab6e1a75 100644 --- a/.github/workflows/ui-automated-tests.yml +++ b/.github/workflows/ui-automated-tests.yml @@ -1,4 +1,4 @@ -name: UI Tests on Windows and MacOS ๐Ÿงช +name: UI Tests on MacOS ๐Ÿงช on: schedule: @@ -71,64 +71,6 @@ jobs: Failed Automated Test type: add - build-windows: - runs-on: - labels: windows-latest - - steps: - - name: Checkout testing directory ๐Ÿ”– - uses: actions/checkout@v3 - with: - repository: Satellite-im/Uplink - - - name: Install Rust ๐Ÿ’ฟ - uses: actions-rs/toolchain@v1 - with: - toolchain: 1.73.0 - override: true - components: rustfmt, clippy - - - name: Build executable ๐Ÿ–ฅ๏ธ - run: cargo build --release -F production_mode - continue-on-error: true - - - name: Create ZIP archive on Windows ๐Ÿ—ณ๏ธ - run: Compress-Archive -Path target/release/uplink.exe -Destination uplinkWindows.zip - - - name: Copy Extensions ๐Ÿ—ณ๏ธ - run: | - mkdir ./ui/extra/extensions - cp -r ./target/release/emoji_selector.d ./ui/extra/extensions/ - cp -r ./target/release/emoji_selector.dll ./ui/extra/extensions/ - cp -r ./target/release/emoji_selector.dll.exp ./ui/extra/extensions/ - cp -r ./target/release/emoji_selector.dll.lib ./ui/extra/extensions/ - cp -r ./target/release/emoji_selector.pdb ./ui/extra/extensions/ - - - name: Upload Executable โฌ†๏ธ - uses: actions/upload-artifact@v3 - with: - name: Uplink-windows-latest - path: uplinkWindows.zip - - - name: Upload Windows Assets - uses: actions/upload-artifact@v3 - with: - name: uplink-windows-assets - path: | - ui/extra/images/ - ui/extra/prism_langs/ - ui/extra/themes/ - ui/extra/extensions/ - - - name: Add label if any of build jobs failed - if: failure() - uses: buildsville/add-remove-label@v2.0.0 - with: - token: ${{ secrets.GITHUB_TOKEN }} - labels: | - Failed Automated Test - type: add - test-mac: needs: build-mac runs-on: macos-13 diff --git a/.github/workflows/ui-automated-windows.yml b/.github/workflows/ui-automated-windows.yml index 6fb807178c0..d5c489ec4bd 100644 --- a/.github/workflows/ui-automated-windows.yml +++ b/.github/workflows/ui-automated-windows.yml @@ -1,4 +1,4 @@ -name: UI Tests on Windows only ๐Ÿงช +name: UI Tests on Windows ๐Ÿงช on: schedule: