From df6c2c5424f1a3714a7c31707fd5b2bbc1f6e6a6 Mon Sep 17 00:00:00 2001 From: Dan Caseley Date: Wed, 22 Jul 2020 17:32:21 +0100 Subject: [PATCH] [TESTS] Idempotence for e2e tests (#2308) * Idempotence for Assorted * Idempotence for Onboarding * Idempotence for Rooms * Remove redundant expects * Fixes and improvements * Remove unneeded sleeps * Make stable following merge * Try solving early taps without long sleep Try solving early taps without long sleep (cont) Temporary CircleCI hack for quicker testing Add screenshots to CircleCI for failed tests Try solving early taps without long sleep (cont. 2) Revert "Temporary CircleCI hack for quicker testing" This reverts commit 4abef3a5827910c05b12ac8b8380275b60e8af4f. * Fix flaky test with a fluent wait on the tap * Add some new sleeps to workaround #2324 * Add test artifacts to gitignore * More longpress for dodgy taps, wait for pin response Co-authored-by: Diego Mello --- .circleci/config.yml | 4 + .gitignore | 1 + e2e/data.js | 7 +- e2e/data/data.cloud.js | 7 +- e2e/data/data.docker.js | 7 +- e2e/helpers/app.js | 51 +++++++- e2e/helpers/data_setup.js | 30 ++++- e2e/tests/assorted/01-changeserver.spec.js | 12 +- e2e/tests/assorted/02-broadcast.spec.js | 29 +---- e2e/tests/assorted/03-profile.spec.js | 10 +- e2e/tests/assorted/04-setting.spec.js | 10 +- e2e/tests/assorted/05-joinpublicroom.spec.js | 14 +- e2e/tests/assorted/06-status.spec.js | 44 ++++--- e2e/tests/init.js | 16 ++- e2e/tests/onboarding/01-onboarding.spec.js | 4 - e2e/tests/onboarding/02-legal.spec.js | 102 ++++++++------- .../onboarding/03-forgotpassword.spec.js | 1 - e2e/tests/onboarding/04-createuser.spec.js | 6 - e2e/tests/onboarding/05-login.spec.js | 6 - e2e/tests/onboarding/06-roomslist.spec.js | 16 ++- e2e/tests/room/01-createroom.spec.js | 43 +++---- e2e/tests/room/02-room.spec.js | 116 ++++++----------- e2e/tests/room/03-roomactions.spec.js | 120 +++++++++--------- e2e/tests/room/04-roominfo.spec.js | 65 ++++------ package.json | 14 ++ 25 files changed, 379 insertions(+), 356 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index bcb01f2a8..899f6808e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -135,6 +135,10 @@ commands: name: Test command: | npx detox test << parameters.folder >> --configuration ios.sim.release --cleanup + when: always + + - store_artifacts: + path: ./artifacts # JOBS jobs: diff --git a/.gitignore b/.gitignore index fee7bf865..18624dd0b 100644 --- a/.gitignore +++ b/.gitignore @@ -58,6 +58,7 @@ buck-out/ coverage +artifacts .vscode/ e2e/docker/rc_test_env/docker-compose.yml e2e/docker/data/db \ No newline at end of file diff --git a/e2e/data.js b/e2e/data.js index 4c4c8ca16..fa153468d 100644 --- a/e2e/data.js +++ b/e2e/data.js @@ -29,10 +29,15 @@ const data = { } }, channels: { - public: { + detoxpublic: { name: 'detox-public' } }, + groups: { + private: { + name: `detox-private-${ value }` + } + }, registeringUser: { username: `newuser${ value }`, password: `password${ value }`, diff --git a/e2e/data/data.cloud.js b/e2e/data/data.cloud.js index 4c4c8ca16..fa153468d 100644 --- a/e2e/data/data.cloud.js +++ b/e2e/data/data.cloud.js @@ -29,10 +29,15 @@ const data = { } }, channels: { - public: { + detoxpublic: { name: 'detox-public' } }, + groups: { + private: { + name: `detox-private-${ value }` + } + }, registeringUser: { username: `newuser${ value }`, password: `password${ value }`, diff --git a/e2e/data/data.docker.js b/e2e/data/data.docker.js index 5a7ed505c..95f31ca9f 100644 --- a/e2e/data/data.docker.js +++ b/e2e/data/data.docker.js @@ -29,10 +29,15 @@ const data = { } }, channels: { - public: { + detoxpublic: { name: 'detox-public' } }, + groups: { + private: { + name: `detox-private-${ value }` + } + }, registeringUser: { username: `newuser${ value }`, password: `password${ value }`, diff --git a/e2e/helpers/app.js b/e2e/helpers/app.js index 88ef3d5ad..92feb61d3 100644 --- a/e2e/helpers/app.js +++ b/e2e/helpers/app.js @@ -31,7 +31,6 @@ async function login(username, password) { await waitFor(element(by.id('login-view'))).toBeVisible().withTimeout(2000); await element(by.id('login-view-email')).replaceText(username); await element(by.id('login-view-password')).replaceText(password); - await sleep(300); await element(by.id('login-view-submit')).tap(); await waitFor(element(by.id('rooms-list-view'))).toBeVisible().withTimeout(10000); } @@ -61,6 +60,33 @@ async function mockMessage(message) { await element(by.label(`${ data.random }${ message }`)).atIndex(0).tap(); }; +async function starMessage(message){ + const messageLabel = `${ data.random }${ message }` + await waitFor(element(by.label(messageLabel))).toBeVisible().withTimeout(5000); + await element(by.label(messageLabel)).atIndex(0).longPress(); + await expect(element(by.id('action-sheet'))).toExist(); + await expect(element(by.id('action-sheet-handle'))).toBeVisible(); + await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5); + await element(by.label('Star')).tap(); + await waitFor(element(by.id('action-sheet'))).toNotExist().withTimeout(5000); +}; + +async function pinMessage(message){ + const messageLabel = `${ data.random }${ message }` + await waitFor(element(by.label(messageLabel)).atIndex(0)).toExist(); + await element(by.label(messageLabel)).atIndex(0).longPress(); + await expect(element(by.id('action-sheet'))).toExist(); + await expect(element(by.id('action-sheet-handle'))).toBeVisible(); + await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5); + await element(by.label('Pin')).tap(); + await waitFor(element(by.id('action-sheet'))).toNotExist().withTimeout(5000); +} + +async function dismissReviewNag(){ + await waitFor(element(by.text('Are you enjoying this app?'))).toExist().withTimeout(60000); + await element(by.label('No').and(by.type('_UIAlertControllerActionView'))).tap(); // Tap `no` on ask for review alert +} + async function tapBack() { await element(by.id('header-back')).atIndex(0).tap(); } @@ -74,7 +100,22 @@ async function searchRoom(room) { await expect(element(by.id('rooms-list-view-search-input'))).toExist(); await waitFor(element(by.id('rooms-list-view-search-input'))).toExist().withTimeout(5000); await element(by.id('rooms-list-view-search-input')).typeText(room); - await sleep(2000); +} + +async function tryTapping(theElement, timeout, longtap = false){ + try { + if(longtap){ + await theElement.longPress() + } else { + await theElement.tap() + } + } catch(e) { + if(timeout <= 0){ //TODO: Maths. How closely has the timeout been honoured here? + throw e + } + await sleep(100) + await tryTapping(theElement, timeout - 100) + } } module.exports = { @@ -84,7 +125,11 @@ module.exports = { login, logout, mockMessage, + starMessage, + pinMessage, + dismissReviewNag, tapBack, sleep, - searchRoom + searchRoom, + tryTapping }; \ No newline at end of file diff --git a/e2e/helpers/data_setup.js b/e2e/helpers/data_setup.js index 84e5927ea..d16b41a55 100644 --- a/e2e/helpers/data_setup.js +++ b/e2e/helpers/data_setup.js @@ -38,7 +38,7 @@ const createUser = async (username, password, name, email) => { } const createChannelIfNotExists = async (channelname) => { - console.log(`Creating channel ${channelname}`) + console.log(`Creating public channel ${channelname}`) try { await rocketchat.post('channels.create', { "name": channelname @@ -49,7 +49,24 @@ const createChannelIfNotExists = async (channelname) => { } catch (infoError) { console.log(JSON.stringify(createError)) console.log(JSON.stringify(infoError)) - throw "Failed to find or create channel" + throw "Failed to find or create public channel" + } + } +} + +const createGroupIfNotExists = async (groupname) => { + console.log(`Creating private group ${groupname}`) + try { + await rocketchat.post('groups.create', { + "name": groupname + }) + } catch (createError) { + try { //Maybe it exists already? + await rocketchat.get(`group.info?roomName=${groupname}`) + } catch (infoError) { + console.log(JSON.stringify(createError)) + console.log(JSON.stringify(infoError)) + throw "Failed to find or create private group" } } } @@ -71,6 +88,15 @@ const setup = async () => { } } + await login(data.users.regular.username, data.users.regular.password) + + for (var groupKey in data.groups) { + if (data.groups.hasOwnProperty(groupKey)) { + const group = data.groups[groupKey] + await createGroupIfNotExists(group.name) + } + } + return } diff --git a/e2e/tests/assorted/01-changeserver.spec.js b/e2e/tests/assorted/01-changeserver.spec.js index 0664970a7..7210d7060 100644 --- a/e2e/tests/assorted/01-changeserver.spec.js +++ b/e2e/tests/assorted/01-changeserver.spec.js @@ -9,12 +9,12 @@ const checkServer = async(server) => { await element(by.id('rooms-list-view-sidebar')).tap(); await waitFor(element(by.id('sidebar-view'))).toBeVisible().withTimeout(2000); await waitFor(element(by.label(label))).toBeVisible().withTimeout(60000); - await expect(element(by.label(label))).toBeVisible(); await element(by.id('sidebar-close-drawer')).tap(); } describe('Change server', () => { before(async() => { + await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); await navigateToLogin(); await login(data.users.regular.username, data.users.regular.password); await waitFor(element(by.id('rooms-list-view'))).toBeVisible().withTimeout(10000); @@ -28,8 +28,6 @@ describe('Change server', () => { await sleep(5000); await element(by.id('rooms-list-header-server-dropdown-button')).tap(); await waitFor(element(by.id('rooms-list-header-server-dropdown'))).toBeVisible().withTimeout(5000); - await expect(element(by.id('rooms-list-header-server-dropdown'))).toExist(); - await sleep(1000); await element(by.id('rooms-list-header-server-add')).tap(); // TODO: refactor @@ -37,19 +35,16 @@ describe('Change server', () => { await element(by.id('new-server-view-input')).replaceText(data.alternateServer); await element(by.id('new-server-view-button')).tap(); await waitFor(element(by.id('workspace-view'))).toBeVisible().withTimeout(60000); - await expect(element(by.id('workspace-view'))).toBeVisible(); await element(by.id('workspace-view-register')).tap(); await waitFor(element(by.id('register-view'))).toBeVisible().withTimeout(2000); - await expect(element(by.id('register-view'))).toBeVisible(); + // Register new user await element(by.id('register-view-name')).replaceText(data.registeringUser.username); await element(by.id('register-view-username')).replaceText(data.registeringUser.username); await element(by.id('register-view-email')).replaceText(data.registeringUser.email); await element(by.id('register-view-password')).replaceText(data.registeringUser.password); - await sleep(1000); await element(by.id('register-view-submit')).tap(); await waitFor(element(by.id('rooms-list-view'))).toBeVisible().withTimeout(60000); - await expect(element(by.id('rooms-list-view'))).toBeVisible(); // For a sanity test, to make sure roomslist is showing correct rooms // app CANNOT show public room created on previous tests @@ -59,11 +54,8 @@ describe('Change server', () => { }); it('should change back', async() => { - await sleep(5000); await element(by.id('rooms-list-header-server-dropdown-button')).tap(); await waitFor(element(by.id('rooms-list-header-server-dropdown'))).toBeVisible().withTimeout(5000); - await expect(element(by.id('rooms-list-header-server-dropdown'))).toExist(); - await sleep(1000); await element(by.id(`rooms-list-header-server-${ data.server }`)).tap(); await waitFor(element(by.id('rooms-list-view'))).toBeVisible().withTimeout(10000); await checkServer(data.server); diff --git a/e2e/tests/assorted/02-broadcast.spec.js b/e2e/tests/assorted/02-broadcast.spec.js index 1b2fcc1db..9e87c5e14 100644 --- a/e2e/tests/assorted/02-broadcast.spec.js +++ b/e2e/tests/assorted/02-broadcast.spec.js @@ -23,28 +23,16 @@ describe('Broadcast room', () => { await waitFor(element(by.id('select-users-view'))).toBeVisible().withTimeout(2000); await element(by.id('select-users-view-search')).replaceText(otheruser.username); await waitFor(element(by.id(`select-users-view-item-${ otheruser.username }`))).toBeVisible().withTimeout(60000); - await expect(element(by.id(`select-users-view-item-${ otheruser.username }`))).toBeVisible(); await element(by.id(`select-users-view-item-${ otheruser.username }`)).tap(); await waitFor(element(by.id(`selected-user-${ otheruser.username }`))).toBeVisible().withTimeout(5000); - await sleep(1000); await element(by.id('selected-users-view-submit')).tap(); - await sleep(1000); await waitFor(element(by.id('create-channel-view'))).toExist().withTimeout(5000); await element(by.id('create-channel-name')).replaceText(`broadcast${ data.random }`); - await sleep(2000); - await element(by.id('create-channel-broadcast')).tap(); - if (device.getPlatform() === 'ios') { //Because this tap is FLAKY on iOS - await expect(element(by.id('create-channel-broadcast'))).toHaveValue('1') - } - await sleep(500); + await element(by.id('create-channel-broadcast')).longPress(); //https://github.com/facebook/react-native/issues/28032 await element(by.id('create-channel-submit')).tap(); await waitFor(element(by.id('room-view'))).toBeVisible().withTimeout(60000); - await expect(element(by.id('room-view'))).toBeVisible(); await waitFor(element(by.id(`room-view-title-broadcast${ data.random }`))).toBeVisible().withTimeout(60000); - await expect(element(by.id(`room-view-title-broadcast${ data.random }`))).toBeVisible(); - await sleep(1000); await element(by.id('room-view-header-actions')).tap(); - await sleep(1000); await waitFor(element(by.id('room-actions-view'))).toBeVisible().withTimeout(5000); await element(by.id('room-actions-info')).tap(); await waitFor(element(by.id('room-info-view'))).toBeVisible().withTimeout(2000); @@ -64,25 +52,19 @@ describe('Broadcast room', () => { it('should login as user without write message authorization and enter room', async() => { await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); await navigateToLogin(); - await element(by.id('login-view-email')).replaceText(otheruser.username); - await element(by.id('login-view-password')).replaceText(otheruser.password); - await sleep(1000); - await element(by.id('login-view-submit')).tap(); + await login(otheruser.username, otheruser.password); + //await waitFor(element(by.id('two-factor'))).toBeVisible().withTimeout(5000); //await expect(element(by.id('two-factor'))).toBeVisible(); //const code = GA.gen(data.alternateUserTOTPSecret); //await element(by.id('two-factor-input')).replaceText(code); - //await sleep(1000); //await element(by.id('two-factor-send')).tap(); - await waitFor(element(by.id('rooms-list-view'))).toBeVisible().withTimeout(10000); + await searchRoom(`broadcast${ data.random }`); await waitFor(element(by.id(`rooms-list-view-item-broadcast${ data.random }`))).toExist().withTimeout(60000); - await expect(element(by.id(`rooms-list-view-item-broadcast${ data.random }`))).toExist(); await element(by.id(`rooms-list-view-item-broadcast${ data.random }`)).tap(); await waitFor(element(by.id('room-view'))).toBeVisible().withTimeout(5000); await waitFor(element(by.id(`room-view-title-broadcast${ data.random }`))).toBeVisible().withTimeout(60000); - await expect(element(by.id(`room-view-title-broadcast${ data.random }`))).toBeVisible(); - await sleep(1000); }); it('should not have messagebox', async() => { @@ -95,7 +77,6 @@ describe('Broadcast room', () => { it('should have the message created earlier', async() => { await waitFor(element(by.label(`${ data.random }message`)).atIndex(0)).toBeVisible().withTimeout(60000); - await expect(element(by.label(`${ data.random }message`)).atIndex(0)).toBeVisible(); }); it('should have reply button', async() => { @@ -104,9 +85,7 @@ describe('Broadcast room', () => { it('should tap on reply button and navigate to direct room', async() => { await element(by.id('message-broadcast-reply')).tap(); - await sleep(1000); await waitFor(element(by.id(`room-view-title-${ testuser.username }`))).toBeVisible().withTimeout(5000); - await expect(element(by.id(`room-view-title-${ testuser.username }`))).toBeVisible(); }); it('should reply broadcasted message', async() => { diff --git a/e2e/tests/assorted/03-profile.spec.js b/e2e/tests/assorted/03-profile.spec.js index e5c321757..a000f6437 100644 --- a/e2e/tests/assorted/03-profile.spec.js +++ b/e2e/tests/assorted/03-profile.spec.js @@ -13,7 +13,7 @@ async function waitForToast() { // await expect(element(by.id('toast'))).toBeVisible(); // await waitFor(element(by.id('toast'))).toBeNotVisible().withTimeout(10000); // await expect(element(by.id('toast'))).toBeNotVisible(); - await sleep(5000); + await sleep(1); } describe('Profile screen', () => { @@ -24,7 +24,6 @@ describe('Profile screen', () => { await element(by.id('rooms-list-view-sidebar')).tap(); await waitFor(element(by.id('sidebar-view'))).toBeVisible().withTimeout(2000); await waitFor(element(by.id('sidebar-profile'))).toBeVisible().withTimeout(2000); - await expect(element(by.id('sidebar-profile'))).toBeVisible(); await element(by.id('sidebar-profile')).tap(); await waitFor(element(by.id('profile-view'))).toBeVisible().withTimeout(2000); }); @@ -60,22 +59,18 @@ describe('Profile screen', () => { it('should have reset avatar button', async() => { await waitFor(element(by.id('profile-view-reset-avatar'))).toExist().whileElement(by.id('profile-view-list')).scroll(scrollDown, 'down'); - await expect(element(by.id('profile-view-reset-avatar'))).toExist(); }); it('should have upload avatar button', async() => { await waitFor(element(by.id('profile-view-upload-avatar'))).toExist().whileElement(by.id('profile-view-list')).scroll(scrollDown, 'down'); - await expect(element(by.id('profile-view-upload-avatar'))).toExist(); }); it('should have avatar url button', async() => { await waitFor(element(by.id('profile-view-avatar-url-button'))).toExist().whileElement(by.id('profile-view-list')).scroll(scrollDown, 'down'); - await expect(element(by.id('profile-view-avatar-url-button'))).toExist(); }); it('should have submit button', async() => { await waitFor(element(by.id('profile-view-submit'))).toExist().whileElement(by.id('profile-view-list')).scroll(scrollDown, 'down'); - await expect(element(by.id('profile-view-submit'))).toExist(); }); }); @@ -84,9 +79,7 @@ describe('Profile screen', () => { await element(by.type('UIScrollView')).atIndex(1).swipe('down'); await element(by.id('profile-view-name')).replaceText(`${ profileChangeUser.username }new`); await element(by.id('profile-view-username')).replaceText(`${ profileChangeUser.username }new`); - await sleep(1000); await element(by.type('UIScrollView')).atIndex(1).swipe('up'); - await sleep(1000); await element(by.id('profile-view-submit')).tap(); await waitForToast(); }); @@ -103,7 +96,6 @@ describe('Profile screen', () => { it('should reset avatar', async() => { await element(by.type('UIScrollView')).atIndex(1).swipe('up'); - await sleep(1000); await element(by.id('profile-view-reset-avatar')).tap(); await waitForToast(); }); diff --git a/e2e/tests/assorted/04-setting.spec.js b/e2e/tests/assorted/04-setting.spec.js index c2cfae6f1..951ccc70d 100644 --- a/e2e/tests/assorted/04-setting.spec.js +++ b/e2e/tests/assorted/04-setting.spec.js @@ -1,12 +1,18 @@ const { device, expect, element, by, waitFor } = require('detox'); +const { navigateToLogin, login } = require('../../helpers/app'); + +const data = require('../../data'); + +const testuser = data.users.regular describe('Settings screen', () => { before(async() => { - await device.launchApp({ newInstance: true }); + await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); + await navigateToLogin(); + await login(testuser.username, testuser.password); await waitFor(element(by.id('rooms-list-view'))).toBeVisible().withTimeout(10000); - await expect(element(by.id('rooms-list-view'))).toBeVisible(); await element(by.id('rooms-list-view-sidebar')).tap(); await waitFor(element(by.id('sidebar-view'))).toBeVisible().withTimeout(2000); await waitFor(element(by.id('sidebar-settings'))).toBeVisible().withTimeout(2000); diff --git a/e2e/tests/assorted/05-joinpublicroom.spec.js b/e2e/tests/assorted/05-joinpublicroom.spec.js index d68d1a955..1c946f0c2 100644 --- a/e2e/tests/assorted/05-joinpublicroom.spec.js +++ b/e2e/tests/assorted/05-joinpublicroom.spec.js @@ -2,12 +2,12 @@ const { device, expect, element, by, waitFor } = require('detox'); const data = require('../../data'); -const { mockMessage, tapBack, sleep, searchRoom } = require('../../helpers/app'); +const { navigateToLogin, login, mockMessage, tapBack, sleep, searchRoom } = require('../../helpers/app'); -const room = 'detox-public'; +const testuser = data.users.regular +const room = data.channels.detoxpublic.name; async function navigateToRoom() { - await sleep(2000); await searchRoom(room); await waitFor(element(by.id(`rooms-list-view-item-${ room }`)).atIndex(0)).toBeVisible().withTimeout(60000); await element(by.id(`rooms-list-view-item-${ room }`)).atIndex(0).tap(); @@ -15,15 +15,15 @@ async function navigateToRoom() { } async function navigateToRoomActions() { - await sleep(2000); await element(by.id('room-view-header-actions')).tap(); - await sleep(2000); await waitFor(element(by.id('room-actions-view'))).toBeVisible().withTimeout(5000); } describe('Join public room', () => { before(async() => { - await device.launchApp({ newInstance: true }); + await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); + await navigateToLogin(); + await login(testuser.username, testuser.password); await navigateToRoom(); }); @@ -167,9 +167,7 @@ describe('Join public room', () => { await element(by.text('Yes, leave it!')).tap(); await waitFor(element(by.id('rooms-list-view'))).toBeVisible().withTimeout(10000); // await element(by.id('rooms-list-view-search')).typeText(''); - await sleep(2000); await waitFor(element(by.id(`rooms-list-view-item-${ room }`))).toBeNotVisible().withTimeout(60000); - await expect(element(by.id(`rooms-list-view-item-${ room }`))).toBeNotVisible(); }); }); }); diff --git a/e2e/tests/assorted/06-status.spec.js b/e2e/tests/assorted/06-status.spec.js index ee592d41f..887dcb1e0 100644 --- a/e2e/tests/assorted/06-status.spec.js +++ b/e2e/tests/assorted/06-status.spec.js @@ -1,14 +1,21 @@ const { expect, element, by, waitFor } = require('detox'); -const { sleep } = require('../../helpers/app'); +const { navigateToLogin, login, sleep } = require('../../helpers/app'); + +const data = require('../../data'); +const testuser = data.users.regular async function waitForToast() { - await sleep(5000); + await sleep(1); } describe('Status screen', () => { - before(async() => { + before(async () => { + await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); + await navigateToLogin(); + await login(testuser.username, testuser.password); + await element(by.id('rooms-list-view-sidebar')).tap(); await waitFor(element(by.id('sidebar-view'))).toBeVisible().withTimeout(2000); await waitFor(element(by.id('sidebar-custom-status'))).toBeVisible().withTimeout(2000); @@ -17,30 +24,27 @@ describe('Status screen', () => { await waitFor(element(by.id('status-view'))).toBeVisible().withTimeout(2000); }); - describe('Render', async() => { - it('should have status input', async() => { + describe('Render', async () => { + it('should have status input', async () => { await expect(element(by.id('status-view-input'))).toBeVisible(); await expect(element(by.id('status-view-online'))).toExist(); await expect(element(by.id('status-view-busy'))).toExist(); await expect(element(by.id('status-view-away'))).toExist(); await expect(element(by.id('status-view-offline'))).toExist(); - }); - }); - - describe('Usage', async() => { - it('should change status', async() => { - await sleep(1000); - await element(by.id('status-view-busy')).tap(); - await sleep(1000); - await expect(element(by.id('status-view-current-busy'))).toExist(); - }); + }); + }); - it('should change status text', async() => { + describe('Usage', async () => { + it('should change status', async () => { + await element(by.id('status-view-busy')).tap(); + await expect(element(by.id('status-view-current-busy'))).toExist(); + }); + + it('should change status text', async () => { await element(by.id('status-view-input')).replaceText('status-text-new'); - await sleep(1000); await element(by.id('status-view-submit')).tap(); await waitForToast(); await waitFor(element(by.label('status-text-new').withAncestor(by.id('sidebar-custom-status')))).toBeVisible().withTimeout(2000); - }); - }); -}); + }); + }); +}); \ No newline at end of file diff --git a/e2e/tests/init.js b/e2e/tests/init.js index bef12f6d3..9eaa721b6 100644 --- a/e2e/tests/init.js +++ b/e2e/tests/init.js @@ -1,11 +1,21 @@ const detox = require('detox'); const config = require('../../package.json').detox; const dataSetup = require('../helpers/data_setup') +const adapter = require('detox/runners/mocha/adapter'); before(async() => { - await dataSetup() - await detox.init(config, { launchApp: false }); - await device.launchApp({ permissions: { notifications: 'YES' } }); + await Promise.all([dataSetup(), detox.init(config, { launchApp: false })]) + //await dataSetup() + //await detox.init(config, { launchApp: false }); + //await device.launchApp({ permissions: { notifications: 'YES' } }); +}); + +beforeEach(async function() { + await adapter.beforeEach(this); +}); + +afterEach(async function() { + await adapter.afterEach(this); }); after(async() => { diff --git a/e2e/tests/onboarding/01-onboarding.spec.js b/e2e/tests/onboarding/01-onboarding.spec.js index c84928d60..9c049099e 100644 --- a/e2e/tests/onboarding/01-onboarding.spec.js +++ b/e2e/tests/onboarding/01-onboarding.spec.js @@ -31,7 +31,6 @@ describe('Onboarding', () => { it('should navigate to join a workspace', async() => { await element(by.id('join-workspace')).tap(); await waitFor(element(by.id('new-server-view'))).toBeVisible().withTimeout(60000); - await expect(element(by.id('new-server-view'))).toBeVisible(); }); it('should enter an invalid server and get error', async() => { @@ -39,14 +38,12 @@ describe('Onboarding', () => { await element(by.id('new-server-view-button')).tap(); const errorText = 'Oops!'; await waitFor(element(by.text(errorText))).toBeVisible().withTimeout(60000); - await expect(element(by.text(errorText))).toBeVisible(); await element(by.text('OK')).tap(); }); it('should tap on "Join our open workspace" and navigate', async() => { await element(by.id('new-server-view-open')).tap(); await waitFor(element(by.id('workspace-view'))).toBeVisible().withTimeout(60000); - await expect(element(by.id('workspace-view'))).toBeVisible(); }); it('should enter a valid server without login services and navigate to login', async() => { @@ -57,7 +54,6 @@ describe('Onboarding', () => { await element(by.id('new-server-view-input')).replaceText(data.server); await element(by.id('new-server-view-button')).tap(); await waitFor(element(by.id('workspace-view'))).toBeVisible().withTimeout(60000); - await expect(element(by.id('workspace-view'))).toBeVisible(); }); }); }); diff --git a/e2e/tests/onboarding/02-legal.spec.js b/e2e/tests/onboarding/02-legal.spec.js index e8109ece5..191e0647c 100644 --- a/e2e/tests/onboarding/02-legal.spec.js +++ b/e2e/tests/onboarding/02-legal.spec.js @@ -4,54 +4,62 @@ const { const { navigateToRegister, navigateToLogin } = require('../../helpers/app'); describe('Legal screen', () => { - it('should have legal button on login', async() => { - await device.launchApp({ newInstance: true }); - await navigateToLogin(); - await waitFor(element(by.id('login-view-more'))).toBeVisible().withTimeout(60000); - await expect(element(by.id('login-view-more'))).toBeVisible(); - }); - it('should navigate to legal from login', async() => { - await waitFor(element(by.id('login-view-more'))).toBeVisible().withTimeout(60000); - await element(by.id('login-view-more')).tap(); - }); - - it('should have legal button on register', async() => { - await device.launchApp({ newInstance: true }); - await navigateToRegister(); - await waitFor(element(by.id('register-view-more'))).toBeVisible().withTimeout(60000); - await expect(element(by.id('register-view-more'))).toBeVisible(); - }); - - it('should navigate to legal from register', async() => { - await waitFor(element(by.id('register-view-more'))).toBeVisible().withTimeout(60000); - await element(by.id('register-view-more')).tap(); - }); - - it('should have legal screen', async() => { - await expect(element(by.id('legal-view'))).toBeVisible(); - }); - - it('should have terms of service button', async() => { - await expect(element(by.id('legal-terms-button'))).toBeVisible(); - }); - - it('should have privacy policy button', async() => { - await expect(element(by.id('legal-privacy-button'))).toBeVisible(); - }); + describe('From Login', () => { + before(async() => { + await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); + await navigateToLogin(); + }); - - // We can't simulate how webview behaves, so I had to disable :( - // it('should navigate to terms', async() => { - // await element(by.id('legal-terms-button')).tap(); - // await waitFor(element(by.id('terms-view'))).toBeVisible().withTimeout(2000); - // await expect(element(by.id('terms-view'))).toBeVisible(); - // }); + it('should have legal button on login', async() => { + await waitFor(element(by.id('login-view-more'))).toBeVisible().withTimeout(60000); + }); - // it('should navigate to privacy', async() => { - // await tapBack(); - // await element(by.id('legal-privacy-button')).tap(); - // await waitFor(element(by.id('privacy-view'))).toBeVisible().withTimeout(2000); - // await expect(element(by.id('privacy-view'))).toBeVisible(); - // }); + it('should navigate to legal from login', async() => { + await expect(element(by.id('login-view-more'))).toBeVisible(); + await element(by.id('login-view-more')).tap(); + await waitFor(element(by.id('legal-view'))).toBeVisible().withTimeout(4000) + }); + }); + + describe('From Register', () => { + before(async() => { + await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); + await navigateToRegister(); + }); + + it('should have legal button on register', async() => { + await waitFor(element(by.id('register-view-more'))).toBeVisible().withTimeout(60000); + }); + + it('should navigate to legal from register', async() => { + await expect(element(by.id('register-view-more'))).toBeVisible(); + await element(by.id('register-view-more')).tap(); + await waitFor(element(by.id('legal-view'))).toBeVisible().withTimeout(4000); + }); + + it('should have terms of service button', async() => { + await expect(element(by.id('legal-terms-button'))).toBeVisible(); + }); + + it('should have privacy policy button', async() => { + await expect(element(by.id('legal-privacy-button'))).toBeVisible(); + }); + + // We can't simulate how webview behaves, so I had to disable :( + /* + it('should navigate to terms', async() => { + await element(by.id('legal-terms-button')).tap(); + await waitFor(element(by.id('terms-view'))).toBeVisible().withTimeout(2000); + await expect(element(by.id('terms-view'))).toBeVisible(); + }); + + it('should navigate to privacy', async() => { + await tapBack(); + await element(by.id('legal-privacy-button')).tap(); + await waitFor(element(by.id('privacy-view'))).toBeVisible().withTimeout(2000); + await expect(element(by.id('privacy-view'))).toBeVisible(); + }); + */ + }); }); diff --git a/e2e/tests/onboarding/03-forgotpassword.spec.js b/e2e/tests/onboarding/03-forgotpassword.spec.js index 2fa710469..88d4c3e90 100644 --- a/e2e/tests/onboarding/03-forgotpassword.spec.js +++ b/e2e/tests/onboarding/03-forgotpassword.spec.js @@ -32,7 +32,6 @@ describe('Forgot password screen', () => { await element(by.id('forgot-password-view-submit')).tap(); await element(by.text('OK')).tap(); await waitFor(element(by.id('login-view'))).toBeVisible().withTimeout(60000); - await expect(element(by.id('login-view'))).toBeVisible(); }); }); }); diff --git a/e2e/tests/onboarding/04-createuser.spec.js b/e2e/tests/onboarding/04-createuser.spec.js index 6abd8fc16..aa75807f2 100644 --- a/e2e/tests/onboarding/04-createuser.spec.js +++ b/e2e/tests/onboarding/04-createuser.spec.js @@ -53,10 +53,8 @@ describe('Create user screen', () => { await element(by.id('register-view-username')).replaceText(data.registeringUser.username); await element(by.id('register-view-email')).replaceText(data.users.existing.email); await element(by.id('register-view-password')).replaceText(data.registeringUser.password); - await sleep(300); await element(by.id('register-view-submit')).tap(); await waitFor(element(by.text('Email already exists. [403]')).atIndex(0)).toExist().withTimeout(10000); - await expect(element(by.text('Email already exists. [403]')).atIndex(0)).toExist(); await element(by.text('OK')).tap(); }); @@ -65,10 +63,8 @@ describe('Create user screen', () => { await element(by.id('register-view-username')).replaceText(data.users.existing.username); await element(by.id('register-view-email')).replaceText(data.registeringUser.email); await element(by.id('register-view-password')).replaceText(data.registeringUser.password); - await sleep(300); await element(by.id('register-view-submit')).tap(); await waitFor(element(by.text('Username is already in use')).atIndex(0)).toExist().withTimeout(10000); - await expect(element(by.text('Username is already in use')).atIndex(0)).toExist(); await element(by.text('OK')).tap(); }); @@ -77,10 +73,8 @@ describe('Create user screen', () => { await element(by.id('register-view-username')).replaceText(data.registeringUser.username); await element(by.id('register-view-email')).replaceText(data.registeringUser.email); await element(by.id('register-view-password')).replaceText(data.registeringUser.password); - await sleep(300); await element(by.id('register-view-submit')).tap(); await waitFor(element(by.id('rooms-list-view'))).toBeVisible().withTimeout(60000); - await expect(element(by.id('rooms-list-view'))).toBeVisible(); }); }); }); diff --git a/e2e/tests/onboarding/05-login.spec.js b/e2e/tests/onboarding/05-login.spec.js index 3734b543d..7c6b4853c 100644 --- a/e2e/tests/onboarding/05-login.spec.js +++ b/e2e/tests/onboarding/05-login.spec.js @@ -44,33 +44,27 @@ describe('Login screen', () => { it('should navigate to register', async() => { await element(by.id('login-view-register')).tap(); await waitFor(element(by.id('register-view'))).toBeVisible().withTimeout(2000); - await expect(element(by.id('register-view'))).toBeVisible(); await tapBack(); }); it('should navigate to forgot password', async() => { await element(by.id('login-view-forgot-password')).tap(); await waitFor(element(by.id('forgot-password-view'))).toExist().withTimeout(2000); - await expect(element(by.id('forgot-password-view'))).toExist(); await tapBack(); }); it('should insert wrong password and get error', async() => { await element(by.id('login-view-email')).replaceText(data.users.regular.username); await element(by.id('login-view-password')).replaceText('NotMyActualPassword'); - await sleep(300); await element(by.id('login-view-submit')).tap(); await waitFor(element(by.text('Your credentials were rejected! Please try again.'))).toBeVisible().withTimeout(10000); - await expect(element(by.text('Your credentials were rejected! Please try again.'))).toBeVisible(); await element(by.text('OK')).tap(); }); it('should login with success', async() => { await element(by.id('login-view-password')).replaceText(data.users.regular.password); - await sleep(300); await element(by.id('login-view-submit')).tap(); await waitFor(element(by.id('rooms-list-view'))).toBeVisible().withTimeout(60000); - await expect(element(by.id('rooms-list-view'))).toBeVisible(); }); }); }); diff --git a/e2e/tests/onboarding/06-roomslist.spec.js b/e2e/tests/onboarding/06-roomslist.spec.js index 5e7e1e8aa..bbe0b886b 100644 --- a/e2e/tests/onboarding/06-roomslist.spec.js +++ b/e2e/tests/onboarding/06-roomslist.spec.js @@ -1,9 +1,17 @@ const { device, expect, element, by, waitFor } = require('detox'); -const { logout, tapBack, sleep, searchRoom } = require('../../helpers/app'); +const { login, navigateToLogin, logout, tapBack, sleep, searchRoom } = require('../../helpers/app'); +const data = require('../../data'); describe('Rooms list screen', () => { + + before(async() => { + await device.launchApp({ permissions: { notifications: 'YES' }, newInstance: true, delete: true }); + await navigateToLogin(); + await login(data.users.regular.username, data.users.regular.password) + }); + describe('Render', () => { it('should have rooms list screen', async() => { await expect(element(by.id('rooms-list-view'))).toBeVisible(); @@ -29,18 +37,12 @@ describe('Rooms list screen', () => { it('should search room and navigate', async() => { await searchRoom('rocket.cat'); await waitFor(element(by.id('rooms-list-view-item-rocket.cat'))).toBeVisible().withTimeout(60000); - await expect(element(by.id('rooms-list-view-item-rocket.cat'))).toBeVisible(); await element(by.id('rooms-list-view-item-rocket.cat')).tap(); await waitFor(element(by.id('room-view'))).toBeVisible().withTimeout(10000); - await expect(element(by.id('room-view'))).toBeVisible(); await waitFor(element(by.id('room-view-title-rocket.cat'))).toBeVisible().withTimeout(60000); - await expect(element(by.id('room-view-title-rocket.cat'))).toBeVisible(); await tapBack(); await waitFor(element(by.id('rooms-list-view'))).toBeVisible().withTimeout(2000); - await expect(element(by.id('rooms-list-view'))).toBeVisible(); - await sleep(2000); await waitFor(element(by.id('rooms-list-view-item-rocket.cat'))).toExist().withTimeout(60000); - await expect(element(by.id('rooms-list-view-item-rocket.cat'))).toExist(); }); it('should logout', async() => { diff --git a/e2e/tests/room/01-createroom.spec.js b/e2e/tests/room/01-createroom.spec.js index 1cfbf16a7..35b007dba 100644 --- a/e2e/tests/room/01-createroom.spec.js +++ b/e2e/tests/room/01-createroom.spec.js @@ -2,48 +2,50 @@ const { device, expect, element, by, waitFor } = require('detox'); const data = require('../../data'); -const { tapBack, sleep, navigateToLogin, login } = require('../../helpers/app'); +const { tapBack, sleep, navigateToLogin, login, tryTapping } = require('../../helpers/app'); + + describe('Create room screen', () => { before(async() => { + await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); await navigateToLogin(); await login(data.users.regular.username, data.users.regular.password); - await element(by.id('rooms-list-view-create-channel')).tap(); - await waitFor(element(by.id('new-message-view'))).toExist().withTimeout(2000); }); describe('New Message', async() => { + before(async() => { + await element(by.id('rooms-list-view-create-channel')).tap(); + }); + describe('Render', async() => { it('should have new message screen', async() => { - await expect(element(by.id('new-message-view'))).toExist(); + await waitFor(element(by.id('new-message-view'))).toBeVisible().withTimeout(2000); }); it('should have search input', async() => { - await waitFor(element(by.id('new-message-view-search'))).toExist().withTimeout(2000); - await expect(element(by.id('new-message-view-search'))).toExist(); + await waitFor(element(by.id('new-message-view-search'))).toBeVisible().withTimeout(2000); }); }) describe('Usage', async() => { it('should back to rooms list', async() => { - await sleep(1000); + await waitFor(element(by.id('new-message-view-close'))).toBeVisible().withTimeout(2000); await element(by.id('new-message-view-close')).tap(); - await waitFor(element(by.id('rooms-list-view'))).toExist().withTimeout(2000); - await expect(element(by.id('rooms-list-view'))).toExist(); - await element(by.id('rooms-list-view-create-channel')).tap(); + + await waitFor(element(by.id('rooms-list-view'))).toBeVisible().withTimeout(2000); + + await tryTapping(element(by.id('rooms-list-view-create-channel')), 3000); + //await element(by.id('rooms-list-view-create-channel')).tap(); await waitFor(element(by.id('new-message-view'))).toExist().withTimeout(2000); - await expect(element(by.id('new-message-view'))).toExist(); }); it('should search user and navigate', async() => { await element(by.id('new-message-view-search')).replaceText('rocket.cat'); await waitFor(element(by.id('new-message-view-item-rocket.cat'))).toExist().withTimeout(60000); - await expect(element(by.id('new-message-view-item-rocket.cat'))).toExist(); await element(by.id('new-message-view-item-rocket.cat')).tap(); await waitFor(element(by.id('room-view'))).toExist().withTimeout(10000); - await expect(element(by.id('room-view'))).toExist(); await waitFor(element(by.id('room-view-title-rocket.cat'))).toExist().withTimeout(60000); - await expect(element(by.id('room-view-title-rocket.cat'))).toExist(); await tapBack(); await waitFor(element(by.id('rooms-list-view'))).toExist().withTimeout(2000); }); @@ -51,11 +53,8 @@ describe('Create room screen', () => { it('should navigate to select users', async() => { await element(by.id('rooms-list-view-create-channel')).tap(); await waitFor(element(by.id('new-message-view'))).toExist().withTimeout(2000); - await expect(element(by.id('new-message-view'))).toExist(); - await sleep(1000); await element(by.id('new-message-view-create-channel')).tap(); await waitFor(element(by.id('select-users-view'))).toExist().withTimeout(2000); - await expect(element(by.id('select-users-view'))).toExist(); }); }) }); @@ -108,7 +107,6 @@ describe('Create room screen', () => { const room = `public${ data.random }`; await element(by.id('create-channel-name')).replaceText(room); await element(by.id('create-channel-type')).tap(); - await sleep(1000); await element(by.id('create-channel-submit')).tap(); await waitFor(element(by.id('room-view'))).toExist().withTimeout(60000); await expect(element(by.id('room-view'))).toExist(); @@ -123,20 +121,15 @@ describe('Create room screen', () => { it('should create private room', async() => { const room = `private${ data.random }`; await waitFor(element(by.id('rooms-list-view'))).toExist().withTimeout(2000); - // await device.launchApp({ newInstance: true }); - await sleep(1000); await element(by.id('rooms-list-view-create-channel')).tap(); await waitFor(element(by.id('new-message-view'))).toExist().withTimeout(2000); - await sleep(1000); await element(by.id('new-message-view-create-channel')).tap(); await waitFor(element(by.id('select-users-view'))).toExist().withTimeout(2000); - await sleep(1000); await element(by.id('select-users-view-item-rocket.cat')).tap(); await waitFor(element(by.id('selected-user-rocket.cat'))).toExist().withTimeout(5000); await element(by.id('selected-users-view-submit')).tap(); await waitFor(element(by.id('create-channel-view'))).toExist().withTimeout(5000); await element(by.id('create-channel-name')).replaceText(room); - await sleep(1000); await element(by.id('create-channel-submit')).tap(); await waitFor(element(by.id('room-view'))).toExist().withTimeout(60000); await expect(element(by.id('room-view'))).toExist(); @@ -152,17 +145,13 @@ describe('Create room screen', () => { const room = `empty${ data.random }`; await waitFor(element(by.id('rooms-list-view'))).toExist().withTimeout(2000); // await device.launchApp({ newInstance: true }); - await sleep(1000); await element(by.id('rooms-list-view-create-channel')).tap(); await waitFor(element(by.id('new-message-view'))).toExist().withTimeout(2000); - await sleep(1000); await element(by.id('new-message-view-create-channel')).tap(); await waitFor(element(by.id('select-users-view'))).toExist().withTimeout(2000); - await sleep(1000); await element(by.id('selected-users-view-submit')).tap(); await waitFor(element(by.id('create-channel-view'))).toExist().withTimeout(5000); await element(by.id('create-channel-name')).replaceText(room); - await sleep(1000); await element(by.id('create-channel-submit')).tap(); await waitFor(element(by.id('room-view'))).toExist().withTimeout(60000); await expect(element(by.id('room-view'))).toExist(); diff --git a/e2e/tests/room/02-room.spec.js b/e2e/tests/room/02-room.spec.js index 86fdfc21f..00d5d434d 100644 --- a/e2e/tests/room/02-room.spec.js +++ b/e2e/tests/room/02-room.spec.js @@ -2,27 +2,29 @@ const { device, expect, element, by, waitFor } = require('detox'); const data = require('../../data'); -const { mockMessage, tapBack, sleep, searchRoom } = require('../../helpers/app'); +const { navigateToLogin, login, mockMessage, tapBack, sleep, searchRoom, starMessage, pinMessage, dismissReviewNag, tryTapping } = require('../../helpers/app'); -async function navigateToRoom() { - await searchRoom(`private${ data.random }`); - await waitFor(element(by.id(`rooms-list-view-item-private${ data.random }`))).toExist().withTimeout(60000); - await element(by.id(`rooms-list-view-item-private${ data.random }`)).tap(); +async function navigateToRoom(roomName) { + await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); + await navigateToLogin(); + await login(data.users.regular.username, data.users.regular.password); + await searchRoom(`${ roomName }`); + await waitFor(element(by.id(`rooms-list-view-item-${ roomName }`))).toExist().withTimeout(60000); + await element(by.id(`rooms-list-view-item-${ roomName }`)).tap(); await waitFor(element(by.id('room-view'))).toBeVisible().withTimeout(5000); } describe('Room screen', () => { - const mainRoom = `private${ data.random }`; + const mainRoom = data.groups.private.name; before(async() => { - await navigateToRoom(); + await navigateToRoom(mainRoom); }); describe('Render', async() => { it('should have room screen', async() => { await expect(element(by.id('room-view'))).toExist(); await waitFor(element(by.id(`room-view-title-${ mainRoom }`))).toExist().withTimeout(5000); - await expect(element(by.id(`room-view-title-${ mainRoom }`))).toExist(); }); // Render - Header @@ -69,22 +71,15 @@ describe('Room screen', () => { await expect(element(by.label(`${ data.random }message`)).atIndex(0)).toExist(); }); - it('should ask for review', async() => { - await waitFor(element(by.text('Are you enjoying this app?'))).toExist().withTimeout(60000); - await expect(element(by.text('Are you enjoying this app?')).atIndex(0)).toExist(); - await element(by.label('No').and(by.type('_UIAlertControllerActionView'))).tap(); // Tap `no` on ask for review alert - }) it('should show/hide emoji keyboard', async () => { if (device.getPlatform() === 'android') { await element(by.id('messagebox-open-emoji')).tap(); await waitFor(element(by.id('messagebox-keyboard-emoji'))).toExist().withTimeout(10000); - await expect(element(by.id('messagebox-keyboard-emoji'))).toExist(); await expect(element(by.id('messagebox-close-emoji'))).toExist(); await expect(element(by.id('messagebox-open-emoji'))).toBeNotVisible(); await element(by.id('messagebox-close-emoji')).tap(); await waitFor(element(by.id('messagebox-keyboard-emoji'))).toBeNotVisible().withTimeout(10000); - await expect(element(by.id('messagebox-keyboard-emoji'))).toBeNotVisible(); await expect(element(by.id('messagebox-close-emoji'))).toBeNotVisible(); await expect(element(by.id('messagebox-open-emoji'))).toExist(); } @@ -94,10 +89,8 @@ describe('Room screen', () => { await element(by.id('messagebox-input')).tap(); await element(by.id('messagebox-input')).typeText(':joy'); await waitFor(element(by.id('messagebox-container'))).toExist().withTimeout(10000); - await expect(element(by.id('messagebox-container'))).toExist(); await element(by.id('messagebox-input')).clearText(); await waitFor(element(by.id('messagebox-container'))).toBeNotVisible().withTimeout(10000); - await expect(element(by.id('messagebox-container'))).toBeNotVisible(); }); it('should show and tap on emoji autocomplete', async() => { @@ -105,8 +98,6 @@ describe('Room screen', () => { await element(by.id('messagebox-input')).replaceText(':'); await element(by.id('messagebox-input')).typeText('joy'); // workaround for number keyboard await waitFor(element(by.id('messagebox-container'))).toExist().withTimeout(10000); - await expect(element(by.id('messagebox-container'))).toExist(); - await sleep(1000); await element(by.id('mention-item-joy')).tap(); await expect(element(by.id('messagebox-input'))).toHaveText(':joy: '); await element(by.id('messagebox-input')).clearText(); @@ -116,25 +107,22 @@ describe('Room screen', () => { const username = data.users.regular.username await element(by.id('messagebox-input')).tap(); await element(by.id('messagebox-input')).typeText(`@${ username }`); - await waitFor(element(by.id('messagebox-container'))).toExist().withTimeout(60000); - await expect(element(by.id('messagebox-container'))).toExist(); - await sleep(1000); - await element(by.id(`mention-item-${ username }`)).tap(); + await waitFor(element(by.id('messagebox-container'))).toExist().withTimeout(4000); + await waitFor(element(by.id(`mention-item-${ username }`))).toBeVisible().withTimeout(4000) + await tryTapping(element(by.id(`mention-item-${ username }`)), 2000, true); await expect(element(by.id('messagebox-input'))).toHaveText(`@${ username } `); - await element(by.id('messagebox-input')).tap(); + await tryTapping(element(by.id('messagebox-input')), 2000) await element(by.id('messagebox-input')).typeText(`${ data.random }mention`); await element(by.id('messagebox-send-message')).tap(); // await waitFor(element(by.label(`@${ data.user } ${ data.random }mention`)).atIndex(0)).toExist().withTimeout(60000); - await sleep(2000); }); it('should show and tap on room autocomplete', async() => { await element(by.id('messagebox-input')).tap(); await element(by.id('messagebox-input')).typeText('#general'); - await waitFor(element(by.id('messagebox-container'))).toExist().withTimeout(60000); - await expect(element(by.id('messagebox-container'))).toExist(); - await sleep(1000); - await element(by.id('mention-item-general')).tap(); + //await waitFor(element(by.id('messagebox-container'))).toExist().withTimeout(4000); + await waitFor(element(by.id('mention-item-general'))).toBeVisible().withTimeout(4000); + await tryTapping(element(by.id('mention-item-general')), 2000, true) await expect(element(by.id('messagebox-input'))).toHaveText('#general '); await element(by.id('messagebox-input')).clearText(); }); @@ -147,7 +135,6 @@ describe('Room screen', () => { await expect(element(by.id('action-sheet-handle'))).toBeVisible(); await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5); await element(by.label('Permalink')).tap(); - await sleep(1000); // TODO: test clipboard }); @@ -158,28 +145,20 @@ describe('Room screen', () => { await expect(element(by.id('action-sheet-handle'))).toBeVisible(); await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5); await element(by.label('Copy')).tap(); - await sleep(1000); // TODO: test clipboard }); it('should star message', async() => { - await element(by.label(`${ data.random }message`)).atIndex(0).longPress(); - await expect(element(by.id('action-sheet'))).toExist(); - await expect(element(by.id('action-sheet-handle'))).toBeVisible(); - await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5); - await element(by.label('Star')).tap(); - await sleep(1000); - await waitFor(element(by.id('action-sheet'))).toNotExist().withTimeout(5000); + await starMessage('message') + await sleep(1000) //https://github.com/RocketChat/Rocket.Chat.ReactNative/issues/2324 await element(by.label(`${ data.random }message`)).atIndex(0).longPress(); await expect(element(by.id('action-sheet'))).toExist(); await expect(element(by.id('action-sheet-handle'))).toBeVisible(); await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5); await waitFor(element(by.label('Unstar'))).toBeVisible().withTimeout(2000); - await expect(element(by.label('Unstar'))).toBeVisible(); await element(by.id('action-sheet-backdrop')).tap(); - await sleep(1000); }); it('should react to message', async() => { @@ -189,14 +168,10 @@ describe('Room screen', () => { await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5); await element(by.id('add-reaction')).tap(); await waitFor(element(by.id('reaction-picker'))).toBeVisible().withTimeout(2000); - await expect(element(by.id('reaction-picker'))).toBeVisible(); await element(by.id('reaction-picker-😃')).tap(); await waitFor(element(by.id('reaction-picker-grinning'))).toExist().withTimeout(2000); - await expect(element(by.id('reaction-picker-grinning'))).toExist(); await element(by.id('reaction-picker-grinning')).tap(); await waitFor(element(by.id('message-reaction-:grinning:'))).toExist().withTimeout(60000); - await expect(element(by.id('message-reaction-:grinning:'))).toExist(); - await sleep(1000); }); it('should react to message with frequently used emoji', async() => { @@ -205,30 +180,27 @@ describe('Room screen', () => { await expect(element(by.id('action-sheet-handle'))).toBeVisible(); await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5); await waitFor(element(by.id('message-actions-emoji-+1'))).toBeVisible().withTimeout(2000); - await expect(element(by.id('message-actions-emoji-+1'))).toBeVisible(); await element(by.id('message-actions-emoji-+1')).tap(); await waitFor(element(by.id('message-reaction-:+1:'))).toBeVisible().withTimeout(60000); - await expect(element(by.id('message-reaction-:+1:'))).toBeVisible(); - await sleep(1000); }); it('should show reaction picker on add reaction button pressed and have frequently used emoji', async() => { await element(by.id('message-add-reaction')).tap(); await waitFor(element(by.id('reaction-picker'))).toExist().withTimeout(2000); - await expect(element(by.id('reaction-picker'))).toExist(); await waitFor(element(by.id('reaction-picker-grinning'))).toExist().withTimeout(2000); - await expect(element(by.id('reaction-picker-grinning'))).toExist(); await element(by.id('reaction-picker-😃')).tap(); await waitFor(element(by.id('reaction-picker-grimacing'))).toExist().withTimeout(2000); await element(by.id('reaction-picker-grimacing')).tap(); await waitFor(element(by.id('message-reaction-:grimacing:'))).toExist().withTimeout(60000); - await sleep(1000); }); + + it('should ask for review', async() => { + await dismissReviewNag() //TODO: Create a proper test for this elsewhere. + }) it('should remove reaction', async() => { await element(by.id('message-reaction-:grinning:')).tap(); await waitFor(element(by.id('message-reaction-:grinning:'))).toBeNotVisible().withTimeout(60000); - await expect(element(by.id('message-reaction-:grinning:'))).toBeNotVisible(); }); it('should edit message', async() => { @@ -241,7 +213,6 @@ describe('Room screen', () => { await element(by.id('messagebox-input')).typeText('ed'); await element(by.id('messagebox-send-message')).tap(); await waitFor(element(by.label(`${ data.random }edited (edited)`)).atIndex(0)).toExist().withTimeout(60000); - await expect(element(by.label(`${ data.random }edited (edited)`)).atIndex(0)).toExist(); }); it('should quote message', async() => { @@ -253,46 +224,39 @@ describe('Room screen', () => { await element(by.label('Quote')).tap(); await element(by.id('messagebox-input')).typeText(`${ data.random }quoted`); await element(by.id('messagebox-send-message')).tap(); - await sleep(1000); // TODO: test if quote was sent }); it('should pin message', async() => { - await waitFor(element(by.label(`${ data.random }edited (edited)`)).atIndex(0)).toExist(); - await element(by.label(`${ data.random }edited (edited)`)).atIndex(0).longPress(); - await expect(element(by.id('action-sheet'))).toExist(); - await expect(element(by.id('action-sheet-handle'))).toBeVisible(); - await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5); - await element(by.label('Pin')).tap(); - await waitFor(element(by.id('action-sheet'))).toNotExist().withTimeout(5000); - await sleep(1500); - - await waitFor(element(by.label(`${ data.random }edited (edited)`)).atIndex(0)).toBeVisible(); - await element(by.label(`${ data.random }edited (edited)`)).atIndex(0).longPress(); - await expect(element(by.id('action-sheet'))).toExist(); + await mockMessage('pin') + await pinMessage('pin') + + await waitFor(element(by.label(`${ data.random }pin`)).atIndex(0)).toBeVisible().withTimeout(2000); + await waitFor(element(by.label('Message pinned')).atIndex(0)).toBeVisible().withTimeout(2000); + await element(by.label(`${ data.random }pin`)).atIndex(0).longPress(); + await waitFor(element(by.id('action-sheet'))).toExist().withTimeout(1000); await expect(element(by.id('action-sheet-handle'))).toBeVisible(); await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5); await waitFor(element(by.label('Unpin'))).toBeVisible().withTimeout(2000); - await expect(element(by.label('Unpin'))).toBeVisible(); await element(by.id('action-sheet-backdrop')).tap(); }); it('should delete message', async() => { - await waitFor(element(by.label(`${ data.random }quoted`)).atIndex(0)).toBeVisible(); - await element(by.label(`${ data.random }quoted`)).atIndex(0).longPress(); + await mockMessage('delete') + + await waitFor(element(by.label(`${ data.random }delete`)).atIndex(0)).toBeVisible(); + await element(by.label(`${ data.random }delete`)).atIndex(0).longPress(); await expect(element(by.id('action-sheet'))).toExist(); await expect(element(by.id('action-sheet-handle'))).toBeVisible(); await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5); await element(by.label('Delete')).tap(); const deleteAlertMessage = 'You will not be able to recover this message!'; - await waitFor(element(by.text(deleteAlertMessage)).atIndex(0)).toExist().withTimeout(10000); - await expect(element(by.text(deleteAlertMessage)).atIndex(0)).toExist(); + await waitFor(element(by.text(deleteAlertMessage)).atIndex(0)).toExist().withTimeout(10000); await element(by.text('Delete')).tap(); - await sleep(1000); - await expect(element(by.label(`${ data.random }quoted`)).atIndex(0)).toNotExist(); + await waitFor(element(by.label(`${ data.random }delete`)).atIndex(0)).toNotExist().withTimeout(2000); }); }); @@ -317,7 +281,6 @@ describe('Room screen', () => { await waitFor(element(by.id(`room-view-title-${ thread }`))).toExist().withTimeout(5000); await expect(element(by.id(`room-view-title-${ thread }`))).toExist(); await tapBack(); - await sleep(1000); }); it('should toggle follow thread', async() => { @@ -332,10 +295,13 @@ describe('Room screen', () => { await waitFor(element(by.id('room-view-header-unfollow'))).toExist().withTimeout(60000); await expect(element(by.id('room-view-header-unfollow'))).toExist(); await tapBack(); - await sleep(1000); }); it('should navigate to thread from thread name', async() => { + await waitFor(element(by.id('room-view-header-actions').and(by.label(` ${ mainRoom }`)))).toBeVisible().withTimeout(2000); + await waitFor(element(by.id('room-view-header-actions').and(by.label(` ${ data.random }thread`)))).toBeNotVisible().withTimeout(2000); + await sleep(500) //TODO: Find a better way to wait for the animation to finish and the messagebox-input to be available and usable :( + await mockMessage('dummymessagebetweenthethread'); await element(by.label(thread)).atIndex(0).longPress(); await expect(element(by.id('action-sheet'))).toExist(); @@ -352,10 +318,10 @@ describe('Room screen', () => { await waitFor(element(by.id(`room-view-title-${ thread }`))).toExist().withTimeout(5000); await expect(element(by.id(`room-view-title-${ thread }`))).toExist(); await tapBack(); - await sleep(1000); }); it('should navigate to thread from threads view', async() => { + await waitFor(element(by.id('room-view-header-threads'))).toExist().withTimeout(1000); await element(by.id('room-view-header-threads')).tap(); await waitFor(element(by.id('thread-messages-view'))).toExist().withTimeout(5000); await expect(element(by.id('thread-messages-view'))).toExist(); diff --git a/e2e/tests/room/03-roomactions.spec.js b/e2e/tests/room/03-roomactions.spec.js index dd5c8defd..bd5b7c6bc 100644 --- a/e2e/tests/room/03-roomactions.spec.js +++ b/e2e/tests/room/03-roomactions.spec.js @@ -2,7 +2,7 @@ const { device, expect, element, by, waitFor } = require('detox'); const data = require('../../data'); -const { tapBack, sleep, searchRoom } = require('../../helpers/app'); +const { navigateToLogin, login, tapBack, sleep, searchRoom, mockMessage, starMessage, pinMessage } = require('../../helpers/app'); const scrollDown = 200; @@ -11,13 +11,12 @@ async function navigateToRoomActions(type) { if (type === 'd') { room = 'rocket.cat'; } else { - room = `private${ data.random }`; + room = data.groups.private.name; } await searchRoom(room); await waitFor(element(by.id(`rooms-list-view-item-${ room }`))).toExist().withTimeout(60000); await element(by.id(`rooms-list-view-item-${ room }`)).tap(); await waitFor(element(by.id('room-view'))).toExist().withTimeout(2000); - await sleep(1000); await element(by.id('room-view-header-actions')).tap(); await waitFor(element(by.id('room-actions-view'))).toExist().withTimeout(5000); } @@ -25,7 +24,6 @@ async function navigateToRoomActions(type) { async function backToActions() { await tapBack(); await waitFor(element(by.id('room-actions-view'))).toExist().withTimeout(2000); - await expect(element(by.id('room-actions-view'))).toExist(); } async function backToRoomsList() { @@ -36,10 +34,16 @@ async function backToRoomsList() { } describe('Room actions screen', () => { + + before(async() => { + await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); + await navigateToLogin(); + await login(data.users.regular.username, data.users.regular.password); + }); + describe('Render', async() => { describe('Direct', async() => { before(async() => { - await device.launchApp({ newInstance: true }); await navigateToRoomActions('d'); }); @@ -197,65 +201,89 @@ describe('Room actions screen', () => { it('should show mentioned messages', async() => { await element(by.id('room-actions-mentioned')).tap(); await waitFor(element(by.id('mentioned-messages-view'))).toExist().withTimeout(2000); - await expect(element(by.id('mentioned-messages-view'))).toExist(); // await waitFor(element(by.text(` ${ data.random }mention`))).toExist().withTimeout(60000); - // await expect(element(by.text(` ${ data.random }mention`))).toExist(); await backToActions(); }); it('should show starred message and unstar it', async() => { + + //Go back to room and send a message + await tapBack(); + await mockMessage('messageToStar'); + + //Star the message + await starMessage('messageToStar') + + //Back into Room Actions + await element(by.id('room-view-header-actions')).tap(); + await waitFor(element(by.id('room-actions-view'))).toExist().withTimeout(5000); + + //Go to starred messages await element(by.id('room-actions-starred')).tap(); await waitFor(element(by.id('starred-messages-view'))).toExist().withTimeout(2000); - await sleep(1000); - await waitFor(element(by.label(`${ data.random }message`).withAncestor(by.id('starred-messages-view')))).toBeVisible().withTimeout(60000); - await expect(element(by.label(`${ data.random }message`).withAncestor(by.id('starred-messages-view')))).toBeVisible(); - await element(by.label(`${ data.random }message`).withAncestor(by.id('starred-messages-view'))).longPress(); - + await waitFor(element(by.label(`${ data.random }messageToStar`).withAncestor(by.id('starred-messages-view')))).toBeVisible().withTimeout(60000); + + //Unstar message + await element(by.label(`${ data.random }messageToStar`).withAncestor(by.id('starred-messages-view'))).longPress(); await expect(element(by.id('action-sheet'))).toExist(); await expect(element(by.id('action-sheet-handle'))).toBeVisible(); await element(by.label('Unstar')).tap(); - await waitFor(element(by.label(`${ data.random }message`).withAncestor(by.id('starred-messages-view')))).toBeNotVisible().withTimeout(60000); - await expect(element(by.label(`${ data.random }message`).withAncestor(by.id('starred-messages-view')))).toBeNotVisible(); + await waitFor(element(by.label(`${ data.random }messageToStar`).withAncestor(by.id('starred-messages-view')))).toBeNotVisible().withTimeout(60000); await backToActions(); }); it('should show pinned message and unpin it', async() => { + + //Go back to room and send a message + await tapBack(); + await mockMessage('messageToPin'); + + //Pin the message + await pinMessage('messageToPin') + + //Back into Room Actions + await element(by.id('room-view-header-actions')).tap(); + await waitFor(element(by.id('room-actions-view'))).toExist().withTimeout(5000); + await waitFor(element(by.id('room-actions-pinned'))).toExist(); await element(by.id('room-actions-pinned')).tap(); await waitFor(element(by.id('pinned-messages-view'))).toExist().withTimeout(2000); - await sleep(1000); - await waitFor(element(by.label(`${ data.random }edited (edited)`).withAncestor(by.id('pinned-messages-view')))).toBeVisible().withTimeout(60000); - await expect(element(by.label(`${ data.random }edited (edited)`).withAncestor(by.id('pinned-messages-view')))).toBeVisible(); - await element(by.label(`${ data.random }edited (edited)`).withAncestor(by.id('pinned-messages-view'))).longPress(); + await waitFor(element(by.label(`${ data.random }messageToPin`).withAncestor(by.id('pinned-messages-view')))).toBeVisible().withTimeout(60000); + await element(by.label(`${ data.random }messageToPin`).withAncestor(by.id('pinned-messages-view'))).longPress(); await expect(element(by.id('action-sheet'))).toExist(); await expect(element(by.id('action-sheet-handle'))).toBeVisible(); await element(by.label('Unpin')).tap(); - await waitFor(element(by.label(`${ data.random }edited (edited)`).withAncestor(by.id('pinned-messages-view')))).toBeNotVisible().withTimeout(60000); - await expect(element(by.label(`${ data.random }edited (edited)`).withAncestor(by.id('pinned-messages-view')))).toBeNotVisible(); + await waitFor(element(by.label(`${ data.random }messageToPin`).withAncestor(by.id('pinned-messages-view')))).toBeNotVisible().withTimeout(60000); await backToActions(); }); it('should search and find a message', async() => { + + //Go back to room and send a message + await tapBack(); + await mockMessage('messageToFind'); + + //Back into Room Actions + await element(by.id('room-view-header-actions')).tap(); + await waitFor(element(by.id('room-actions-view'))).toExist().withTimeout(5000); + await element(by.id('room-actions-search')).tap(); await waitFor(element(by.id('search-messages-view'))).toExist().withTimeout(2000); await expect(element(by.id('search-message-view-input'))).toExist(); - await element(by.id('search-message-view-input')).replaceText(`/${ data.random }message/`); - await waitFor(element(by.label(`${ data.random }message`).withAncestor(by.id('search-messages-view')))).toExist().withTimeout(60000); - await expect(element(by.label(`${ data.random }message`).withAncestor(by.id('search-messages-view')))).toExist(); + await element(by.id('search-message-view-input')).replaceText(`/${ data.random }messageToFind/`); + await waitFor(element(by.label(`${ data.random }messageToFind`).withAncestor(by.id('search-messages-view')))).toExist().withTimeout(60000); await backToActions(); }); }); describe('Notification', async() => { it('should navigate to notification preference view', async() => { - await waitFor(element(by.id('room-actions-notifications'))).toExist(); - await expect(element(by.id('room-actions-notifications'))).toExist(); + await waitFor(element(by.id('room-actions-notifications'))).toExist().withTimeout(2000); await element(by.id('room-actions-notifications')).tap(); await waitFor(element(by.id('notification-preference-view'))).toExist().withTimeout(2000); - await expect(element(by.id('notification-preference-view'))).toExist(); }); it('should have receive notification option', async() => { @@ -271,30 +299,25 @@ describe('Room actions screen', () => { }); it('should have push notification option', async() => { - await waitFor(element(by.id('notification-preference-view-push-notification'))).toExist(); - await expect(element(by.id('notification-preference-view-push-notification'))).toExist(); + await waitFor(element(by.id('notification-preference-view-push-notification'))).toExist().withTimeout(4000); }); it('should have notification audio option', async() => { - await waitFor(element(by.id('notification-preference-view-audio'))).toExist(); - await expect(element(by.id('notification-preference-view-audio'))).toExist(); + await waitFor(element(by.id('notification-preference-view-audio'))).toExist().withTimeout(4000); }); it('should have notification sound option', async() => { // Ugly hack to scroll on detox await element(by.type('UIScrollView')).atIndex(1).scrollTo('bottom'); - await waitFor(element(by.id('notification-preference-view-sound'))).toExist(); - await expect(element(by.id('notification-preference-view-sound'))).toExist(); + await waitFor(element(by.id('notification-preference-view-sound'))).toExist().withTimeout(4000); }); it('should have notification duration option', async() => { - await waitFor(element(by.id('notification-preference-view-notification-duration'))).toExist(); - await expect(element(by.id('notification-preference-view-notification-duration'))).toExist(); + await waitFor(element(by.id('notification-preference-view-notification-duration'))).toExist().withTimeout(4000); }); it('should have email alert option', async() => { - await waitFor(element(by.id('notification-preference-view-email-alert'))).toExist(); - await expect(element(by.id('notification-preference-view-email-alert'))).toExist(); + await waitFor(element(by.id('notification-preference-view-email-alert'))).toExist().withTimeout(4000); }); after(async() => { @@ -309,34 +332,28 @@ describe('Room actions screen', () => { const user = data.users.alternate it('should tap on leave channel and raise alert', async() => { - await waitFor(element(by.id('room-actions-leave-channel'))).toExist(); - await expect(element(by.id('room-actions-leave-channel'))).toExist(); + await waitFor(element(by.id('room-actions-leave-channel'))).toExist().withTimeout(2000); await element(by.id('room-actions-leave-channel')).tap(); await waitFor(element(by.text('Yes, leave it!'))).toExist().withTimeout(2000); - await expect(element(by.text('Yes, leave it!'))).toExist(); await element(by.text('Yes, leave it!')).tap(); - await waitFor(element(by.text('You are the last owner. Please set new owner before leaving the room.'))).toExist().withTimeout(60000); - await expect(element(by.text('You are the last owner. Please set new owner before leaving the room.'))).toExist(); + await waitFor(element(by.text('You are the last owner. Please set new owner before leaving the room.'))).toExist().withTimeout(8000); await element(by.text('OK')).tap(); await waitFor(element(by.id('room-actions-view'))).toExist().withTimeout(2000); }); it('should add user to the room', async() => { - await waitFor(element(by.id('room-actions-add-user'))).toExist(); + await waitFor(element(by.id('room-actions-add-user'))).toExist().withTimeout(4000); await element(by.id('room-actions-add-user')).tap(); await element(by.id('select-users-view-search')).tap(); await element(by.id('select-users-view-search')).replaceText(user.username); - await waitFor(element(by.id(`select-users-view-item-${ user.username }`))).toExist().withTimeout(60000); - await expect(element(by.id(`select-users-view-item-${ user.username }`))).toExist(); + await waitFor(element(by.id(`select-users-view-item-${ user.username }`))).toExist().withTimeout(10000); await element(by.id(`select-users-view-item-${ user.username }`)).tap(); await waitFor(element(by.id(`selected-user-${ user.username }`))).toExist().withTimeout(5000); - await expect(element(by.id(`selected-user-${ user.username }`))).toExist(); await element(by.id('selected-users-view-submit')).tap(); await waitFor(element(by.id('room-actions-view'))).toExist().withTimeout(2000); await element(by.id('room-actions-members')).tap(); await element(by.id('room-members-view-toggle-status')).tap(); await waitFor(element(by.id(`room-members-view-item-${ user.username }`))).toExist().withTimeout(60000); - await expect(element(by.id(`room-members-view-item-${ user.username }`))).toExist(); await backToActions(1); }); @@ -344,26 +361,20 @@ describe('Room actions screen', () => { before(async() => { await element(by.id('room-actions-members')).tap(); await waitFor(element(by.id('room-members-view'))).toExist().withTimeout(2000); - await expect(element(by.id('room-members-view'))).toExist(); }); it('should show all users', async() => { - await sleep(1000); await element(by.id('room-members-view-toggle-status')).tap(); await waitFor(element(by.id(`room-members-view-item-${ user.username }`))).toExist().withTimeout(60000); - await expect(element(by.id(`room-members-view-item-${ user.username }`))).toExist(); }); it('should filter user', async() => { await waitFor(element(by.id(`room-members-view-item-${ user.username }`))).toExist().withTimeout(60000); - await expect(element(by.id(`room-members-view-item-${ user.username }`))).toExist(); await element(by.id('room-members-view-search')).replaceText('rocket'); await waitFor(element(by.id(`room-members-view-item-${ user.username }`))).toBeNotVisible().withTimeout(60000); - await expect(element(by.id(`room-members-view-item-${ user.username }`))).toBeNotVisible(); await element(by.id('room-members-view-search')).tap(); await element(by.id('room-members-view-search')).clearText(''); await waitFor(element(by.id(`room-members-view-item-${ user.username }`))).toExist().withTimeout(60000); - await expect(element(by.id(`room-members-view-item-${ user.username }`))).toExist(); }); // FIXME: mute/unmute isn't working @@ -391,9 +402,7 @@ describe('Room actions screen', () => { await waitFor(element(by.id(`room-members-view-item-${ user.username }`))).toExist().withTimeout(5000); await element(by.id(`room-members-view-item-${ user.username }`)).tap(); await waitFor(element(by.id('room-view'))).toExist().withTimeout(60000); - await expect(element(by.id('room-view'))).toExist(); await waitFor(element(by.id(`room-view-title-${ user.username }`))).toExist().withTimeout(60000); - await expect(element(by.id(`room-view-title-${ user.username }`))).toExist(); await tapBack(); await waitFor(element(by.id('rooms-list-view'))).toExist().withTimeout(2000); }); @@ -407,13 +416,10 @@ describe('Room actions screen', () => { it('should block/unblock user', async() => { await waitFor(element(by.id('room-actions-block-user'))).toExist(); - await sleep(1000); await element(by.id('room-actions-block-user')).tap(); await waitFor(element(by.label('Unblock user'))).toExist().withTimeout(60000); - await expect(element(by.label('Unblock user'))).toExist(); await element(by.id('room-actions-block-user')).tap(); await waitFor(element(by.label('Block user'))).toExist().withTimeout(60000); - await expect(element(by.label('Block user'))).toExist(); }); }); }); diff --git a/e2e/tests/room/04-roominfo.spec.js b/e2e/tests/room/04-roominfo.spec.js index 35a45441b..9382f16cf 100644 --- a/e2e/tests/room/04-roominfo.spec.js +++ b/e2e/tests/room/04-roominfo.spec.js @@ -2,23 +2,23 @@ const { device, expect, element, by, waitFor } = require('detox'); const data = require('../../data'); -const { tapBack, sleep, searchRoom } = require('../../helpers/app'); +const { navigateToLogin, login, tapBack, sleep, searchRoom } = require('../../helpers/app'); + +const privateRoomName = data.groups.private.name async function navigateToRoomInfo(type) { let room; if (type === 'd') { room = 'rocket.cat'; } else { - room = `private${ data.random }`; + room = privateRoomName; } await searchRoom(room); await waitFor(element(by.id(`rooms-list-view-item-${ room }`))).toExist().withTimeout(60000); await element(by.id(`rooms-list-view-item-${ room }`)).tap(); await waitFor(element(by.id('room-view'))).toExist().withTimeout(2000); - await sleep(1000); await element(by.id('room-view-header-actions')).tap(); await waitFor(element(by.id('room-actions-view'))).toExist().withTimeout(5000); - await sleep(1000); await element(by.id('room-actions-info')).tap(); await waitFor(element(by.id('room-info-view'))).toExist().withTimeout(2000); } @@ -28,13 +28,19 @@ async function waitForToast() { // await expect(element(by.id('toast'))).toExist(); // await waitFor(element(by.id('toast'))).toBeNotVisible().withTimeout(10000); // await expect(element(by.id('toast'))).toBeNotVisible(); - await sleep(5000); + await sleep(1); } describe('Room info screen', () => { + + before(async() => { + await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); + await navigateToLogin(); + await login(data.users.regular.username, data.users.regular.password); + }); + describe('Direct', async() => { before(async() => { - await device.launchApp({ newInstance: true }); await navigateToRoomInfo('d'); }); @@ -42,11 +48,16 @@ describe('Room info screen', () => { await expect(element(by.id('room-info-view'))).toExist(); await expect(element(by.id('room-info-view-name'))).toExist(); }); + + after(async() => { + await tapBack() + await tapBack() + await tapBack() + }) }); describe('Channel/Group', async() => { before(async() => { - await device.launchApp({ newInstance: true }); await navigateToRoomInfo('c'); }); @@ -78,7 +89,6 @@ describe('Room info screen', () => { describe('Render Edit', async() => { before(async() => { - await sleep(1000); await waitFor(element(by.id('room-info-view-edit-button'))).toExist().withTimeout(10000); await element(by.id('room-info-view-edit-button')).tap(); await waitFor(element(by.id('room-info-edit-view'))).toExist().withTimeout(2000); @@ -141,7 +151,6 @@ describe('Room info screen', () => { }); describe('Usage', async() => { - const room = `private${ data.random }`; // it('should enter "invalid name" and get error', async() => { // await element(by.type('UIScrollView')).atIndex(1).swipe('down'); // await element(by.id('room-info-edit-view-name')).replaceText('invalid name'); @@ -155,22 +164,17 @@ describe('Room info screen', () => { // }); it('should change room name', async() => { - await element(by.id('room-info-edit-view-name')).replaceText(`${ room }new`); + await element(by.id('room-info-edit-view-name')).replaceText(`${ privateRoomName }new`); await element(by.type('UIScrollView')).atIndex(1).swipe('up'); await element(by.id('room-info-edit-view-submit')).tap(); - await sleep(5000); await tapBack(); await waitFor(element(by.id('room-info-view'))).toExist().withTimeout(2000); - await sleep(1000); - await expect(element(by.id('room-info-view-name'))).toHaveLabel(`${ room }new`); + await expect(element(by.id('room-info-view-name'))).toHaveLabel(`${ privateRoomName }new`); // change name to original await element(by.id('room-info-view-edit-button')).tap(); - await sleep(1000); await waitFor(element(by.id('room-info-edit-view'))).toExist().withTimeout(2000); - await sleep(1000); - await element(by.id('room-info-edit-view-name')).replaceText(`${ room }`); + await element(by.id('room-info-edit-view-name')).replaceText(`${ privateRoomName }`); await element(by.type('UIScrollView')).atIndex(1).swipe('up'); - await sleep(1000); await element(by.id('room-info-edit-view-submit')).tap(); await waitForToast(); await element(by.type('UIScrollView')).atIndex(1).swipe('down'); @@ -184,14 +188,11 @@ describe('Room info screen', () => { await element(by.id('room-info-edit-view-password')).replaceText('abc'); await element(by.type('UIScrollView')).atIndex(1).swipe('up'); await element(by.id('room-info-edit-view-t')).tap(); - await sleep(1000); - await element(by.id('room-info-edit-view-ro')).tap(); - await sleep(1000); + await element(by.id('room-info-edit-view-ro')).longPress(); //https://github.com/facebook/react-native/issues/28032 await element(by.id('room-info-edit-view-react-when-ro')).tap(); - await sleep(1000); await element(by.id('room-info-edit-view-reset')).tap(); // after reset - await expect(element(by.id('room-info-edit-view-name'))).toHaveText(room); + await expect(element(by.id('room-info-edit-view-name'))).toHaveText(privateRoomName); await expect(element(by.id('room-info-edit-view-description'))).toHaveText(''); await expect(element(by.id('room-info-edit-view-topic'))).toHaveText(''); await expect(element(by.id('room-info-edit-view-announcement'))).toHaveText(''); @@ -203,55 +204,45 @@ describe('Room info screen', () => { }); it('should change room description', async() => { - await sleep(1000); await element(by.id('room-info-edit-view-description')).replaceText('new description'); await element(by.type('UIScrollView')).atIndex(1).swipe('up'); await element(by.id('room-info-edit-view-submit')).tap(); await waitForToast(); await tapBack(); await waitFor(element(by.id('room-info-view'))).toExist().withTimeout(2000); - await sleep(1000); await expect(element(by.label('new description').withAncestor(by.id('room-info-view-description')))).toExist(); }); it('should change room topic', async() => { - await sleep(1000); await waitFor(element(by.id('room-info-view-edit-button'))).toExist().withTimeout(10000); await element(by.id('room-info-view-edit-button')).tap(); await waitFor(element(by.id('room-info-edit-view'))).toExist().withTimeout(2000); - await sleep(1000); await element(by.id('room-info-edit-view-topic')).replaceText('new topic'); await element(by.type('UIScrollView')).atIndex(1).swipe('up'); await element(by.id('room-info-edit-view-submit')).tap(); await waitForToast(); await tapBack(); await waitFor(element(by.id('room-info-view'))).toExist().withTimeout(2000); - await sleep(1000); await expect(element(by.label('new topic').withAncestor(by.id('room-info-view-topic')))).toExist(); }); it('should change room announcement', async() => { - await sleep(1000); await waitFor(element(by.id('room-info-view-edit-button'))).toExist().withTimeout(10000); await element(by.id('room-info-view-edit-button')).tap(); await waitFor(element(by.id('room-info-edit-view'))).toExist().withTimeout(2000); - await sleep(1000); await element(by.id('room-info-edit-view-announcement')).replaceText('new announcement'); await element(by.type('UIScrollView')).atIndex(1).swipe('up'); await element(by.id('room-info-edit-view-submit')).tap(); await waitForToast(); await tapBack(); await waitFor(element(by.id('room-info-view'))).toExist().withTimeout(2000); - await sleep(1000); await expect(element(by.label('new announcement').withAncestor(by.id('room-info-view-announcement')))).toExist(); }); it('should change room password', async() => { - await sleep(1000); await waitFor(element(by.id('room-info-view-edit-button'))).toExist().withTimeout(10000); await element(by.id('room-info-view-edit-button')).tap(); await waitFor(element(by.id('room-info-edit-view'))).toExist().withTimeout(2000); - await sleep(1000); await element(by.type('UIScrollView')).atIndex(1).swipe('up'); await element(by.id('room-info-edit-view-password')).replaceText('password'); await element(by.id('room-info-edit-view-submit')).tap(); @@ -259,7 +250,6 @@ describe('Room info screen', () => { }); it('should change room type', async() => { - await sleep(1000); await element(by.type('UIScrollView')).atIndex(1).swipe('up'); await element(by.id('room-info-edit-view-t')).tap(); await element(by.id('room-info-edit-view-submit')).tap(); @@ -282,14 +272,11 @@ describe('Room info screen', () => { // }); it('should archive room', async() => { - await sleep(1000); await element(by.type('UIScrollView')).atIndex(1).swipe('up'); await element(by.id('room-info-edit-view-archive')).tap(); await waitFor(element(by.text('Yes, archive it!'))).toExist().withTimeout(5000); - await expect(element(by.text('Yes, archive it!'))).toExist(); await element(by.text('Yes, archive it!')).tap(); await waitFor(element(by.id('room-info-edit-view-unarchive'))).toExist().withTimeout(60000); - await expect(element(by.id('room-info-edit-view-unarchive'))).toExist(); await expect(element(by.id('room-info-edit-view-archive'))).toBeNotVisible(); // TODO: needs permission to unarchive // await element(by.id('room-info-edit-view-archive')).tap(); @@ -301,16 +288,12 @@ describe('Room info screen', () => { }); it('should delete room', async() => { - await sleep(1000); await element(by.type('UIScrollView')).atIndex(1).swipe('up'); await element(by.id('room-info-edit-view-delete')).tap(); await waitFor(element(by.text('Yes, delete it!'))).toExist().withTimeout(5000); - await expect(element(by.text('Yes, delete it!'))).toExist(); await element(by.text('Yes, delete it!')).tap(); await waitFor(element(by.id('rooms-list-view'))).toExist().withTimeout(10000); - await sleep(2000); - await waitFor(element(by.id(`rooms-list-view-item-${ room }`))).toBeNotVisible().withTimeout(60000); - await expect(element(by.id(`rooms-list-view-item-${ room }`))).toBeNotVisible(); + await waitFor(element(by.id(`rooms-list-view-item-${ privateRoomName }`))).toBeNotVisible().withTimeout(60000); }); }); }); diff --git a/package.json b/package.json index 1f7dd4f17..2ad360966 100644 --- a/package.json +++ b/package.json @@ -196,6 +196,20 @@ "type": "ios.simulator", "device": { "type": "iPhone 11 Pro" + }, + "artifacts": { + "plugins": { + "screenshot": { + "enabled": true, + "shouldTakeAutomaticSnapshots": true, + "keepOnlyFailedTestsArtifacts": true, + "takeWhen": { + "testStart": true, + "testDone": true, + "appNotReady": true + } + } + } } } }