From 2a1b59cd571f9a6dc9d4bbea4cdc24b5f3a17f21 Mon Sep 17 00:00:00 2001 From: Gleidson Daniel Silva Date: Thu, 15 Feb 2024 16:41:03 -0300 Subject: [PATCH] tests: add draft e2e tests (#5553) * chore: update detox * chore: improve mocks * chore: add testId * chore: add e2e tests * add more time * Fix tests * fxi tests * update yarn lock * fix import * wip * test * Fix deep linking tests --------- Co-authored-by: Diego Mello --- .../components/ComposerInput.tsx | 3 +- .../MessageComposer/hooks/useChooseMedia.ts | 2 +- .../helpers/ImagePicker/ImagePicker.mock.ts | 45 +++++++ .../helpers/ImagePicker/ImagePicker.ts | 5 + app/views/ChangeAvatarView/index.tsx | 2 +- app/views/ShareView/index.tsx | 2 +- e2e/helpers/app.ts | 17 ++- e2e/tests/assorted/11-deeplinking.spec.ts | 3 +- e2e/tests/room/02-room.spec.ts | 110 ++++++++++++++++-- package.json | 2 +- yarn.lock | 69 ++++++++++- 11 files changed, 237 insertions(+), 23 deletions(-) create mode 100644 app/lib/methods/helpers/ImagePicker/ImagePicker.mock.ts create mode 100644 app/lib/methods/helpers/ImagePicker/ImagePicker.ts diff --git a/app/containers/MessageComposer/components/ComposerInput.tsx b/app/containers/MessageComposer/components/ComposerInput.tsx index 1d05f9563..dbd33edab 100644 --- a/app/containers/MessageComposer/components/ComposerInput.tsx +++ b/app/containers/MessageComposer/components/ComposerInput.tsx @@ -340,7 +340,8 @@ export const ComposerInput = memo( defaultValue='' multiline keyboardAppearance={theme === 'light' ? 'light' : 'dark'} - testID={`message-composer-input${tmid ? '-thread' : ''}`} + // eslint-disable-next-line no-nested-ternary + testID={`message-composer-input${tmid ? '-thread' : sharing ? '-share' : ''}`} /> ); }) diff --git a/app/containers/MessageComposer/hooks/useChooseMedia.ts b/app/containers/MessageComposer/hooks/useChooseMedia.ts index 282cd11b5..2a43ba5a7 100644 --- a/app/containers/MessageComposer/hooks/useChooseMedia.ts +++ b/app/containers/MessageComposer/hooks/useChooseMedia.ts @@ -1,6 +1,5 @@ import { Alert } from 'react-native'; import DocumentPicker from 'react-native-document-picker'; -import ImagePicker, { ImageOrVideo } from 'react-native-image-crop-picker'; import { IMAGE_PICKER_CONFIG, LIBRARY_PICKER_CONFIG, VIDEO_PICKER_CONFIG } from '../constants'; import { forceJpgExtension } from '../helpers'; @@ -12,6 +11,7 @@ import { getThreadById } from '../../../lib/database/services/Thread'; import Navigation from '../../../lib/navigation/appNavigation'; import { useAppSelector } from '../../../lib/hooks'; import { useRoomContext } from '../../../views/RoomView/context'; +import ImagePicker, { ImageOrVideo } from '../../../lib/methods/helpers/ImagePicker/ImagePicker'; export const useChooseMedia = ({ rid, diff --git a/app/lib/methods/helpers/ImagePicker/ImagePicker.mock.ts b/app/lib/methods/helpers/ImagePicker/ImagePicker.mock.ts new file mode 100644 index 000000000..e4f0cc18b --- /dev/null +++ b/app/lib/methods/helpers/ImagePicker/ImagePicker.mock.ts @@ -0,0 +1,45 @@ +import { random } from 'lodash'; +import { Image as ImageType, ImageOrVideo as ImageOrVideoType } from 'react-native-image-crop-picker'; + +export type Image = ImageType; +export type ImageOrVideo = ImageOrVideoType; + +const mockImageRocketBase64 = + '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'; + +const image = { + exif: null, + filename: 'IMG_0007.PNG', + path: `/tmp/react-native-image-crop-picker/${random(20)}.jpg`, + height: 152, + width: 152, + data: mockImageRocketBase64, + modificationDate: null, + localIdentifier: 'CEEE9916-81FD-4544-9D86-7044DB6C4374/L0/001', + size: 5006, + sourceURL: `/tmp/react-native-image-crop-picker/${random(20)}.jpg`, + mime: 'image/jpeg', + cropRect: { + width: 152, + height: 152, + x: 134, + y: 0 + }, + duration: null, + creationDate: '1679327100' +}; + +export function openPicker(options: any): Promise { + const mockImageRocketBase64 = options?.multiple ? [image] : image; + return Promise.resolve(mockImageRocketBase64); +} + +export function openCamera(options: any): Promise { + const mockImageRocketBase64 = options?.multiple ? [image] : image; + return Promise.resolve(mockImageRocketBase64); +} + +export default { + openPicker, + openCamera +}; diff --git a/app/lib/methods/helpers/ImagePicker/ImagePicker.ts b/app/lib/methods/helpers/ImagePicker/ImagePicker.ts new file mode 100644 index 000000000..cb1a41197 --- /dev/null +++ b/app/lib/methods/helpers/ImagePicker/ImagePicker.ts @@ -0,0 +1,5 @@ +import ImagePicker, { Image as ImageInterface, ImageOrVideo as ImageOrVideoType } from 'react-native-image-crop-picker'; + +export type Image = ImageInterface; +export type ImageOrVideo = ImageOrVideoType; +export default ImagePicker; diff --git a/app/views/ChangeAvatarView/index.tsx b/app/views/ChangeAvatarView/index.tsx index abf2f7637..1b52c843b 100644 --- a/app/views/ChangeAvatarView/index.tsx +++ b/app/views/ChangeAvatarView/index.tsx @@ -25,7 +25,7 @@ import { IAvatar } from '../../definitions'; import AvatarSuggestion from './AvatarSuggestion'; import log from '../../lib/methods/helpers/log'; import { changeRoomsAvatar, changeUserAvatar, resetUserAvatar } from './submitServices'; -import ImagePicker, { Image } from './ImagePicker'; +import ImagePicker, { Image } from '../../lib/methods/helpers/ImagePicker/ImagePicker'; enum AvatarStateActions { CHANGE_AVATAR = 'CHANGE_AVATAR', diff --git a/app/views/ShareView/index.tsx b/app/views/ShareView/index.tsx index 233d72fd8..ac0c045e7 100644 --- a/app/views/ShareView/index.tsx +++ b/app/views/ShareView/index.tsx @@ -126,7 +126,7 @@ class ShareView extends Component { // if is share extension show default back button if (!this.isShareExtension) { - options.headerLeft = () => ; + options.headerLeft = () => ; } if (!attachments.length && !readOnly) { diff --git a/e2e/helpers/app.ts b/e2e/helpers/app.ts index c9a8c6869..abd2f3908 100644 --- a/e2e/helpers/app.ts +++ b/e2e/helpers/app.ts @@ -143,6 +143,20 @@ async function navigateToRoom(room: string) { await checkRoomTitle(room); } +async function navigateToRecentRoom(room: string) { + await waitFor(element(by.id('rooms-list-view'))) + .toExist() + .withTimeout(10000); + await tapAndWaitFor(element(by.id('rooms-list-view-search')), element(by.id('rooms-list-view-search-input')), 5000); + await waitFor(element(by.id(`rooms-list-view-item-${room}`))) + .toBeVisible() + .withTimeout(10000); + await element(by.id(`rooms-list-view-item-${room}`)).tap(); + await waitFor(element(by.id(`room-view-title-${room}`))) + .toBeVisible() + .withTimeout(10000); +} + async function tryTapping( theElement: Detox.IndexableNativeElement | Detox.NativeElement, timeout: number, @@ -261,5 +275,6 @@ export { checkServer, platformTypes, expectValidRegisterOrRetry, - jumpToQuotedMessage + jumpToQuotedMessage, + navigateToRecentRoom }; diff --git a/e2e/tests/assorted/11-deeplinking.spec.ts b/e2e/tests/assorted/11-deeplinking.spec.ts index 18c6a37f1..0d3bb9783 100644 --- a/e2e/tests/assorted/11-deeplinking.spec.ts +++ b/e2e/tests/assorted/11-deeplinking.spec.ts @@ -22,7 +22,7 @@ import random from '../../helpers/random'; const DEEPLINK_METHODS = { AUTH: 'auth', ROOM: 'room' }; -let amp = '&'; +const amp = '&'; const getDeepLink = (method: string, server: string, params?: string) => { const deeplink = `rocketchat://${method}?host=${server.replace(/^(http:\/\/|https:\/\/)/, '')}${amp}${params}`; @@ -47,7 +47,6 @@ describe('Deep linking', () => { const loginResult = await login(user.username, user.password); ({ userId, authToken } = loginResult); const deviceType = device.getPlatform(); - amp = deviceType === 'android' ? '\\&' : '&'; ({ textMatcher } = platformTypes[deviceType]); // create a thread with api const result = await sendMessage(user, room, threadMessage); diff --git a/e2e/tests/room/02-room.spec.ts b/e2e/tests/room/02-room.spec.ts index 70b4e472e..d0e5261a7 100644 --- a/e2e/tests/room/02-room.spec.ts +++ b/e2e/tests/room/02-room.spec.ts @@ -5,22 +5,15 @@ import { login, tapBack, sleep, - searchRoom, tryTapping, platformTypes, TTextMatcher, - mockMessage + mockMessage, + navigateToRoom, + navigateToRecentRoom } from '../../helpers/app'; import { createRandomRoom, createRandomUser, ITestUser, sendMessage } from '../../helpers/data_setup'; -async function navigateToRoom(roomName: string) { - await searchRoom(`${roomName}`); - await element(by.id(`rooms-list-view-item-${roomName}`)).tap(); - await waitFor(element(by.id('room-view'))) - .toBeVisible() - .withTimeout(5000); -} - describe('Room screen', () => { let room: string; let alertButtonType: string; @@ -371,6 +364,103 @@ describe('Room screen', () => { .toExist() .withTimeout(60000); await element(by[textMatcher](replyMessage)).atIndex(0).tap(); + await tapBack(); + }); + + it('should save message and quote draft correctly', async () => { + const newUser = await createRandomUser(); + const { name: draftRoom } = await createRandomRoom(newUser, 'c'); + const draftMessage = 'draft'; + const originalMessage = '123'; + const quoteMessage = '123456'; + await sendMessage(newUser, draftRoom, originalMessage); + await waitFor(element(by.id('rooms-list-view'))) + .toBeVisible() + .withTimeout(5000); + await navigateToRoom(draftRoom); + await waitFor(element(by[textMatcher](originalMessage)).atIndex(0)) + .toBeVisible() + .withTimeout(10000); + await element(by.id('room-view-join-button')).tap(); + await waitFor(element(by.id('room-view-join-button'))) + .not.toBeVisible() + .withTimeout(10000); + // add draft + await element(by.id('message-composer-input')).typeText(draftMessage); + await tapBack(); + await navigateToRecentRoom(draftRoom); + await sleep(500); // wait for animation + await expect(element(by.id('message-composer-input'))).toHaveText(draftMessage); + // add quote to draft + await tryTapping(element(by[textMatcher](originalMessage)).atIndex(0), 2000, true); + await waitFor(element(by.id('action-sheet'))) + .toExist() + .withTimeout(5000); + await expect(element(by.id('action-sheet-handle'))).toBeVisible(); + await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5); + await element(by[textMatcher]('Quote')).atIndex(0).tap(); + await waitFor(element(by.id(`markdown-preview-${originalMessage}`))) + .toBeVisible() + .withTimeout(10000); + await tapBack(); + await navigateToRecentRoom(draftRoom); + await sleep(500); // wait for animation + await waitFor(element(by.id(`markdown-preview-${originalMessage}`))) + .toBeVisible() + .withTimeout(10000); + // edit draft with quote + await element(by.id('message-composer-input')).replaceText(quoteMessage); + await tapBack(); + await navigateToRecentRoom(draftRoom); + await sleep(500); // wait for animation + await expect(element(by.id('message-composer-input'))).toHaveText(quoteMessage); + // send message + await waitFor(element(by.id('message-composer-send'))) + .toExist() + .withTimeout(5000); + await element(by.id('message-composer-send')).tap(); + await waitFor(element(by.id(`reply-${newUser.name}-${originalMessage}`).withDescendant(by[textMatcher](originalMessage)))) + .toBeVisible() + .withTimeout(5000); + await expect(element(by.id('message-composer-input'))).toHaveText(''); + }); + + it('should edit message on shareview and after close the text needs to be changed on roomView', async () => { + const draftShareMessage = 'draftShare'; + const originalMessage = '123'; + await element(by.id('message-composer-input')).typeText(draftShareMessage); + await element(by.id('message-composer-actions')).tap(); + await waitFor(element(by.id('action-sheet'))) + .toExist() + .withTimeout(2000); + await element(by[textMatcher]('Choose from library')).atIndex(0).tap(); + await sleep(300); // wait for animation + await waitFor(element(by.id('message-composer-input-share'))) + .toHaveText(draftShareMessage) + .withTimeout(2000); + await element(by.id('message-composer-input-share')).replaceText(draftShareMessage + originalMessage); + await element(by.id('share-view-close')).tap(); + await sleep(500); // wait for animation + await waitFor(element(by.id('message-composer-input'))) + .toHaveText(draftShareMessage + originalMessage) + .withTimeout(2000); + // add quote to draft + await tryTapping(element(by[textMatcher](originalMessage)).atIndex(0), 2000, true); + await waitFor(element(by.id('action-sheet'))) + .toExist() + .withTimeout(2000); + await expect(element(by.id('action-sheet-handle'))).toBeVisible(); + await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5); + await element(by[textMatcher]('Quote')).atIndex(0).tap(); + await element(by.id('message-composer-actions')).tap(); + await waitFor(element(by.id('action-sheet'))) + .toExist() + .withTimeout(2000); + await element(by[textMatcher]('Choose from library')).atIndex(0).tap(); + await sleep(500); // wait for animation + await waitFor(element(by.id(`markdown-preview-${originalMessage}`)).atIndex(0)) + .toExist() + .withTimeout(20000); }); }); }); diff --git a/package.json b/package.json index 9fda32b15..d730f34e4 100644 --- a/package.json +++ b/package.json @@ -192,7 +192,7 @@ "babel-loader": "8.3.0", "babel-plugin-transform-remove-console": "^6.9.4", "codecov": "^3.8.3", - "detox": "20.11.0", + "detox": "20.17.1", "eslint": "^7.32.0", "eslint-config-prettier": "^8.5.0", "eslint-plugin-import": "2.26.0", diff --git a/yarn.lock b/yarn.lock index aeb7e571d..e0da0b81a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4335,6 +4335,11 @@ find-up "^5.0.0" js-yaml "^4.1.0" +"@flatten-js/interval-tree@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@flatten-js/interval-tree/-/interval-tree-1.1.2.tgz#fcc891da48bc230392884be01c26fe8c625702e8" + integrity sha512-OwLoV9E/XM6b7bes2rSFnGNjyRy7vcoIHFTnmBR2WAaZTf0Fe4EX4GdA65vU1KgFAasti7iRSg2dZfYd1Zt00Q== + "@gar/promisify@^1.0.1": version "1.1.3" resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" @@ -8625,6 +8630,16 @@ builtins@^1.0.3: resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" integrity sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ== +bunyamin@^1.5.0: + version "1.5.2" + resolved "https://registry.yarnpkg.com/bunyamin/-/bunyamin-1.5.2.tgz#681db204c0b16531369d5c1f6c89dc8d760b7558" + integrity sha512-Xp2nfqk33zt3nX90OSTkLVOc5N+1zdR3MWvfLHoIrm3cGRkdxPTPYB9CCgrDV8oum5rbghJjAbmXFXOrRXvMtg== + dependencies: + "@flatten-js/interval-tree" "^1.1.2" + multi-sort-stream "^1.0.4" + stream-json "^1.7.5" + trace-event-lib "^1.3.1" + bunyan-debug-stream@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/bunyan-debug-stream/-/bunyan-debug-stream-3.1.0.tgz#78309c67ad85cfb8f011155334152c49209dcda8" @@ -8642,6 +8657,18 @@ bunyan@^1.8.12: mv "~2" safe-json-stringify "~1" +bunyan@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-2.0.5.tgz#9dd056755220dddd8b5bb9cf76f3d0d766e96e71" + integrity sha512-Jvl74TdxCN6rSP9W1I6+UOUtwslTDqsSFkDqZlFb/ilaSvQ+bZAnXT/GT97IZ5L+Vph0joPZPhxUyn6FLNmFAA== + dependencies: + exeunt "1.1.0" + optionalDependencies: + dtrace-provider "~0.8" + moment "^2.19.3" + mv "~2" + safe-json-stringify "~1" + bytebuffer@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/bytebuffer/-/bytebuffer-5.0.1.tgz#582eea4b1a873b6d020a48d58df85f0bba6cfddd" @@ -10145,10 +10172,10 @@ detect-port@^1.3.0: address "^1.0.1" debug "^2.6.0" -detox@20.11.0: - version "20.11.0" - resolved "https://registry.yarnpkg.com/detox/-/detox-20.11.0.tgz#f240e01db12334e0706b7f3477e59b8a5e4358c8" - integrity sha512-01LpETlZwfo2V7Awo+5ccUbee7E1lvH3ldLlmXxsx3mQ0pEA65f9CaO+FWhtUGYh7vQRMOQ9SnzYdej/ydQ7iQ== +detox@20.17.1: + version "20.17.1" + resolved "https://registry.yarnpkg.com/detox/-/detox-20.17.1.tgz#55b9615cf5937819e1257fbf03fb2d2d58cf2acc" + integrity sha512-10pey6CR9D5GSloRkH60ObBGZ8VS11H7iuBNY7qq6jO2swiqqckHhPLRXfH9+WGR7l3vDnfU+G/gQs7JxQkJwA== dependencies: ajv "^8.6.3" bunyan "^1.8.12" @@ -10162,6 +10189,7 @@ detox@20.11.0: funpermaproxy "^1.1.0" glob "^8.0.3" ini "^1.3.4" + jest-environment-emit "^1.0.5" json-cycle "^1.3.0" lodash "^4.17.11" multi-sort-stream "^1.0.3" @@ -11138,6 +11166,11 @@ execa@^5.0.0, execa@^5.1.1: signal-exit "^3.0.3" strip-final-newline "^2.0.0" +exeunt@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/exeunt/-/exeunt-1.1.0.tgz#af72db6f94b3cb75e921aee375d513049843d284" + integrity sha512-dd++Yn/0Fp+gtJ04YHov7MeAii+LFivJc6KqnJNfplzLVUkUDrfKoQDTLlCgzcW15vY5hKlHasWeIsQJ8agHsw== + exif-parser@^0.1.12: version "0.1.12" resolved "https://registry.yarnpkg.com/exif-parser/-/exif-parser-0.1.12.tgz#58a9d2d72c02c1f6f02a0ef4a9166272b7760922" @@ -13769,6 +13802,20 @@ jest-each@^28.1.3: jest-util "^28.1.3" pretty-format "^28.1.3" +jest-environment-emit@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/jest-environment-emit/-/jest-environment-emit-1.0.5.tgz#e6f33451f98b88ccd48e9e1188bb535880f03c1b" + integrity sha512-OsQ08AhYxkkyDBTIow+9ogNmJheQIGWQKp0Nku+1ToLWjAj2Pd6LmypN8HgUIqYHs4HFcqkQ25kaf1qExmoZpg== + dependencies: + bunyamin "^1.5.0" + bunyan "^2.0.5" + bunyan-debug-stream "^3.1.0" + funpermaproxy "^1.1.0" + lodash.merge "^4.6.2" + node-ipc "9.2.1" + strip-ansi "^6.0.0" + tslib "^2.5.3" + jest-environment-node@^28.1.3: version "28.1.3" resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-28.1.3.tgz#7e74fe40eb645b9d56c0c4b70ca4357faa349be5" @@ -15787,7 +15834,7 @@ ms@2.1.3: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -multi-sort-stream@^1.0.3: +multi-sort-stream@^1.0.3, multi-sort-stream@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/multi-sort-stream/-/multi-sort-stream-1.0.4.tgz#e4348edc9edc36e16333e531a90c0f166235cc99" integrity sha512-hAZ8JOEQFbgdLe8HWZbb7gdZg0/yAIHF00Qfo3kd0rXFv96nXe+/bPTrKHZ2QMHugGX4FiAyET1Lt+jiB+7Qlg== @@ -19586,6 +19633,13 @@ stream-json@^1.7.4: dependencies: stream-chain "^2.2.5" +stream-json@^1.7.5: + version "1.8.0" + resolved "https://registry.yarnpkg.com/stream-json/-/stream-json-1.8.0.tgz#53f486b2e3b4496c506131f8d7260ba42def151c" + integrity sha512-HZfXngYHUAr1exT4fxlbc1IOce1RYxp2ldeaf97LYCOPSoOqY/1Psp7iGvpb+6JIOgkra9zDYnPX01hGAHzEPw== + dependencies: + stream-chain "^2.2.5" + stream-shift@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" @@ -20476,6 +20530,11 @@ tslib@^2.0.0, tslib@^2.0.1, tslib@^2.1.0, tslib@^2.3.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== +tslib@^2.5.3: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"