From 5b7f5224040309a742bb09f93fd4cb86c4587a4e Mon Sep 17 00:00:00 2001 From: Joseph Baylon Date: Tue, 23 Feb 2021 08:09:47 -0800 Subject: [PATCH] MM-30423 Detox/E2E: Add e2e for MM-T3192, MM-T3215, MM-T3219, MM-T3221, MM-T3256 (#5180) * MM-30423 Detox/E2E: Add e2e for MM-T3192, MM-T3215, MM-T3219, MM-T3221, MM-T3256 * Update detox/e2e/test/smoke_test/direct_messages.e2e.js Co-authored-by: Saturnino Abril * Update detox/e2e/test/smoke_test/email_notifications.e2e.js Co-authored-by: Saturnino Abril * Update detox/e2e/test/smoke_test/email_notifications.e2e.js Co-authored-by: Saturnino Abril * Renamed return object status to userStatus Co-authored-by: Saturnino Abril --- .../post_pre_header.test.js.snap | 5 + app/components/post_header/post_pre_header.js | 1 + .../notification_settings.test.js.snap | 2 + .../notification_settings.js | 4 +- ...cation_settings_email.android.test.js.snap | 9 +- ...tification_settings_email.ios.test.js.snap | 2 + .../notification_settings_email.android.js | 15 +- .../notification_settings_email.ios.js | 3 + app/screens/settings/section_item.js | 11 +- detox/e2e/support/server_api/channel.js | 2 + detox/e2e/support/server_api/index.js | 2 + detox/e2e/support/server_api/preference.js | 3 +- detox/e2e/support/server_api/status.js | 60 +++ detox/e2e/support/server_api/system.js | 50 +- detox/e2e/support/test_config.js | 2 + detox/e2e/support/ui/component/post.js | 3 + detox/e2e/support/ui/component/post_list.js | 9 +- detox/e2e/support/ui/screen/index.js | 2 + .../ui/screen/notification_settings.js | 4 + .../ui/screen/notification_settings_email.js | 70 +++ detox/e2e/support/utils.js | 55 +++ .../channel_notification_default.e2e.js | 15 +- .../test/smoke_test/direct_messages.e2e.js | 84 ++++ .../smoke_test/email_notifications.e2e.js | 227 +++++++++ .../test/smoke_test/favorite_channels.e2e.js | 52 ++- ...e_channel.e2e.js => group_messages.e2e.js} | 2 +- .../e2e/test/smoke_test/saved_messages.e2e.js | 90 ++++ detox/package-lock.json | 430 +++++++++--------- detox/package.json | 8 +- package-lock.json | 12 +- package.json | 2 +- 31 files changed, 982 insertions(+), 254 deletions(-) create mode 100644 detox/e2e/support/server_api/status.js create mode 100644 detox/e2e/support/ui/screen/notification_settings_email.js create mode 100644 detox/e2e/test/smoke_test/direct_messages.e2e.js create mode 100644 detox/e2e/test/smoke_test/email_notifications.e2e.js rename detox/e2e/test/smoke_test/{group_message_channel.e2e.js => group_messages.e2e.js} (98%) create mode 100644 detox/e2e/test/smoke_test/saved_messages.e2e.js diff --git a/app/components/post_header/__snapshots__/post_pre_header.test.js.snap b/app/components/post_header/__snapshots__/post_pre_header.test.js.snap index 6423ed6d4..d9560f956 100644 --- a/app/components/post_header/__snapshots__/post_pre_header.test.js.snap +++ b/app/components/post_header/__snapshots__/post_pre_header.test.js.snap @@ -54,6 +54,7 @@ exports[`PostPreHeader should match snapshot when flagged and not pinned 1`] = ` "lineHeight": 15, } } + testID="post_pre_header.text" /> @@ -133,6 +134,7 @@ exports[`PostPreHeader should match snapshot when pinned and flagged 1`] = ` "lineHeight": 15, } } + testID="post_pre_header.text" /> @@ -194,6 +196,7 @@ exports[`PostPreHeader should match snapshot when pinned and flagged but skippin "lineHeight": 15, } } + testID="post_pre_header.text" /> @@ -253,6 +256,7 @@ exports[`PostPreHeader should match snapshot when pinned and flagged but skippin "lineHeight": 15, } } + testID="post_pre_header.text" /> @@ -312,6 +316,7 @@ exports[`PostPreHeader should match snapshot when pinned and not flagged 1`] = ` "lineHeight": 15, } } + testID="post_pre_header.text" /> diff --git a/app/components/post_header/post_pre_header.js b/app/components/post_header/post_pre_header.js index 8dab1dd68..0cd90bca0 100644 --- a/app/components/post_header/post_pre_header.js +++ b/app/components/post_header/post_pre_header.js @@ -84,6 +84,7 @@ export default class PostPreHeader extends PureComponent { diff --git a/app/screens/settings/notification_settings/__snapshots__/notification_settings.test.js.snap b/app/screens/settings/notification_settings/__snapshots__/notification_settings.test.js.snap index 6c722a026..02f5fdf22 100644 --- a/app/screens/settings/notification_settings/__snapshots__/notification_settings.test.js.snap +++ b/app/screens/settings/notification_settings/__snapshots__/notification_settings.test.js.snap @@ -274,6 +274,7 @@ NotificationSettings { onPress={[Function]} separator={true} showArrow={true} + testID="notification_settings.mentions_replies.action" theme={ Object { "awayIndicator": "#ffbc42", @@ -353,6 +354,7 @@ NotificationSettings { onPress={[Function]} separator={false} showArrow={true} + testID="notification_settings.email.action" theme={ Object { "awayIndicator": "#ffbc42", diff --git a/app/screens/settings/notification_settings/notification_settings.js b/app/screens/settings/notification_settings/notification_settings.js index 003c7e296..e7ac2b59b 100644 --- a/app/screens/settings/notification_settings/notification_settings.js +++ b/app/screens/settings/notification_settings/notification_settings.js @@ -215,9 +215,9 @@ export default class NotificationSettings extends PureComponent { separator={true} showArrow={showArrow} theme={theme} + testID='notification_settings.mentions_replies.action' /> {autoResponder} diff --git a/app/screens/settings/notification_settings_email/__snapshots__/notification_settings_email.android.test.js.snap b/app/screens/settings/notification_settings_email/__snapshots__/notification_settings_email.android.test.js.snap index c5cbbd6ea..bad774e6c 100644 --- a/app/screens/settings/notification_settings_email/__snapshots__/notification_settings_email.android.test.js.snap +++ b/app/screens/settings/notification_settings_email/__snapshots__/notification_settings_email.android.test.js.snap @@ -16,6 +16,7 @@ exports[`NotificationSettingsEmailAndroid should match snapshot 1`] = ` id="user.settings.notifications.email.send" /> } + testID="notification_settings_email.send.action" theme={ Object { "awayIndicator": "#ffbc42", @@ -56,7 +57,9 @@ exports[`NotificationSettingsEmailAndroid should match snapshot 2`] = ` transparent={true} visible={false} > - + @@ -80,11 +83,13 @@ exports[`NotificationSettingsEmailAndroid should match snapshot 2`] = ` Object { "checked": true, "label": "Immediately", + "testID": "notification_settings_email.immediately.action", "value": "30", }, Object { "checked": false, "label": "Never", + "testID": "notification_settings_email.never.action", "value": "0", }, ] @@ -108,6 +113,7 @@ exports[`NotificationSettingsEmailAndroid should match snapshot 2`] = ` } selected={true} + testID="notification_settings_email.immediately.action" theme={ Object { "awayIndicator": "#ffbc42", @@ -100,6 +101,7 @@ exports[`NotificationSettingsEmailIos should match snapshot, renderEmailSection /> } selected={false} + testID="notification_settings_email.never.action" theme={ Object { "awayIndicator": "#ffbc42", diff --git a/app/screens/settings/notification_settings_email/notification_settings_email.android.js b/app/screens/settings/notification_settings_email/notification_settings_email.android.js index dda15017d..b9f892c0b 100644 --- a/app/screens/settings/notification_settings_email/notification_settings_email.android.js +++ b/app/screens/settings/notification_settings_email/notification_settings_email.android.js @@ -92,6 +92,7 @@ class NotificationSettingsEmailAndroid extends NotificationSettingsEmailBase { action={this.showEmailModal} actionType='default' theme={theme} + testID='notification_settings_email.send.action' /> ); } @@ -122,6 +123,7 @@ class NotificationSettingsEmailAndroid extends NotificationSettingsEmailBase { }), value: Preferences.INTERVAL_IMMEDIATE.toString(), checked: newInterval === Preferences.INTERVAL_IMMEDIATE.toString(), + testID: 'notification_settings_email.immediately.action', }]; if (enableEmailBatching) { @@ -149,6 +151,7 @@ class NotificationSettingsEmailAndroid extends NotificationSettingsEmailBase { }), value: Preferences.INTERVAL_NEVER.toString(), checked: newInterval === Preferences.INTERVAL_NEVER.toString(), + testID: 'notification_settings_email.never.action', }); return ( @@ -158,7 +161,10 @@ class NotificationSettingsEmailAndroid extends NotificationSettingsEmailBase { visible={this.state.showEmailNotificationsModal} onRequestClose={this.handleClose} > - + @@ -190,6 +196,7 @@ class NotificationSettingsEmailAndroid extends NotificationSettingsEmailBase { + {enableEmailBatching && @@ -98,6 +99,7 @@ class NotificationSettingsEmailIos extends NotificationSettingsEmailBase { actionValue={Preferences.INTERVAL_NEVER.toString()} selected={newInterval === Preferences.INTERVAL_NEVER.toString()} theme={theme} + testID='notification_settings_email.never.action' /> } @@ -120,6 +122,7 @@ class NotificationSettingsEmailIos extends NotificationSettingsEmailBase { ); } else if (actionType === ActionTypes.TOGGLE) { @@ -60,14 +61,20 @@ function sectionItem(props) { const labelComponent = React.cloneElement( label, - {style: style.label}, + { + style: style.label, + testID: `${testID}.label`, + }, ); let descriptionComponent; if (description) { descriptionComponent = React.cloneElement( description, - {style: style.description}, + { + style: style.description, + testID: `${testID}.description`, + }, ); } diff --git a/detox/e2e/support/server_api/channel.js b/detox/e2e/support/server_api/channel.js index 0e231a8f4..17e1286be 100644 --- a/detox/e2e/support/server_api/channel.js +++ b/detox/e2e/support/server_api/channel.js @@ -44,6 +44,7 @@ export const apiCreateChannel = async ({teamId = null, type = 'O', prefix = 'cha * Create a direct message channel. * See https://api.mattermost.com/#tag/channels/paths/~1channels~1direct/post * @param {Array} userIds - the two user IDs to be in the direct message + * @return {Object} returns {channel} on success or {error, status} on error */ export const apiCreateDirectChannel = async (userIds = []) => { try { @@ -62,6 +63,7 @@ export const apiCreateDirectChannel = async (userIds = []) => { * Create a group message channel. * See https://api.mattermost.com/#tag/channels/paths/~1channels~1group/post * @param {Array} userIds - user IDs to be in the group message channel + * @return {Object} returns {channel} on success or {error, status} on error */ export const apiCreateGroupChannel = async (userIds = []) => { try { diff --git a/detox/e2e/support/server_api/index.js b/detox/e2e/support/server_api/index.js index 1cff9ba25..5504a5c5e 100644 --- a/detox/e2e/support/server_api/index.js +++ b/detox/e2e/support/server_api/index.js @@ -6,6 +6,7 @@ import Ldap from './ldap'; import Post from './post'; import Preference from './preference'; import Setup from './setup'; +import Status from './status'; import System from './system'; import Team from './team'; import User from './user'; @@ -16,6 +17,7 @@ export { Post, Preference, Setup, + Status, System, Team, User, diff --git a/detox/e2e/support/server_api/preference.js b/detox/e2e/support/server_api/preference.js index 4a1c13f2d..cdbac9ab6 100644 --- a/detox/e2e/support/server_api/preference.js +++ b/detox/e2e/support/server_api/preference.js @@ -18,6 +18,7 @@ import {getResponseFromError} from './common'; /** * Save the user's preferences. + * See https://api.mattermost.com/#tag/preferences/paths/~1users~1{user_id}~1preferences/put * @param {string} userId - the user ID * @param {Array} preferences - a list of user's preferences * @return {string} returns {status} on success or {error, status} on error @@ -70,9 +71,9 @@ export const apiSaveTeamsOrderPreference = (userId, orderedTeamIds = []) => { }; export const Preference = { - apiSaveUserPreferences, apiSaveFavoriteChannelPreference, apiSaveTeamsOrderPreference, + apiSaveUserPreferences, }; export default Preference; diff --git a/detox/e2e/support/server_api/status.js b/detox/e2e/support/server_api/status.js new file mode 100644 index 000000000..a78c78ef1 --- /dev/null +++ b/detox/e2e/support/server_api/status.js @@ -0,0 +1,60 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import client from './client'; +import {getResponseFromError} from './common'; + +// **************************************************************** +// Status +// See https://api.mattermost.com/#tag/status +// +// Exported API function should have the following: +// - documented using JSDoc +// - meaningful description +// - match the referenced API endpoints +// - parameter/s defined by `@param` +// - return value defined by `@return` +// **************************************************************** + +/** + * Get user status. + * See https://api.mattermost.com/#tag/status/paths/~1users~1{user_id}~1status/get + * @param {string} userId - the user ID + * @return {Object} returns {userStatus} on success or {error, status} on error + */ +export const apiGetUserStatus = async (userId) => { + try { + const response = await client.get(`/api/v4/users/${userId}/status`); + + return {userStatus: response.data}; + } catch (err) { + return getResponseFromError(err); + } +}; + +/** + * Update user status. + * See https://api.mattermost.com/#tag/status/paths/~1users~1{user_id}~1status/put + * @param {string} userId - the user ID + * @param {string} status - the user status, can be online, away, offline and dnd + * @return {Object} returns {userStatus} on success or {error, status} on error + */ +export const apiUpdateUserStatus = async (userId, status = 'online') => { + try { + const response = await client.put( + `/api/v4/users/${userId}/status`, + {user_id: userId, status}, + ); + + return {userStatus: response.data}; + } catch (err) { + return getResponseFromError(err); + } +}; + +export const Status = { + apiGetUserStatus, + apiUpdateUserStatus, +}; + +export default Status; diff --git a/detox/e2e/support/server_api/system.js b/detox/e2e/support/server_api/system.js index 8009b94b8..7948a25c6 100644 --- a/detox/e2e/support/server_api/system.js +++ b/detox/e2e/support/server_api/system.js @@ -27,13 +27,23 @@ import defaultServerConfig from './default_config.json'; /** * Check system health. - * See https://api.mattermost.com/#tag/system/paths/~1system~1ping/get - * @return {Object} returns {data} on success or {error, status} on error */ export const apiCheckSystemHealth = async () => { + const {data} = await apiPingServerStatus(); + jestExpect(data.status).toEqual('OK'); + jestExpect(data.database_status).toEqual('OK'); + jestExpect(data.filestore_status).toEqual('OK'); +}; + +/** + * Send a test email. + * See https://api.mattermost.com/#tag/system/paths/~1email~1test/post + * @return {Object} returns response on success or {error, status} on error + */ +export const apiEmailTest = async () => { try { - const response = await client.get('/api/v4/system/ping?get_server_status=true'); - return {data: response.data}; + const response = await client.post('/api/v4/email/test'); + return response; } catch (err) { return getResponseFromError(err); } @@ -42,6 +52,7 @@ export const apiCheckSystemHealth = async () => { /** * Get configuration. * See https://api.mattermost.com/#tag/system/paths/~1config/get + * @return {Object} returns {config} on success or {error, status} on error */ export const apiGetConfig = async () => { try { @@ -57,6 +68,7 @@ export const apiGetConfig = async () => { * Update configuration. * See https://api.mattermost.com/#tag/system/paths/~1config/put * @param {Object} newConfig - specific config to update + * @return {Object} returns {config} on success or {error, status} on error */ export const apiUpdateConfig = async (newConfig = {}) => { try { @@ -101,6 +113,28 @@ export const apiGetClientLicense = async () => { } }; +/** + * Ping server status. + * See https://api.mattermost.com/#tag/system/paths/~1system~1ping/get + * @return {Object} returns {data} on success or {error, status} on error + */ +export const apiPingServerStatus = async () => { + try { + const response = await client.get('/api/v4/system/ping?get_server_status=true'); + return {data: response.data}; + } catch (err) { + return getResponseFromError(err); + } +}; + +/** + * Require SMTP server to be running. + */ +export const apiRequireSMTPServer = async () => { + const {status} = await apiEmailTest(); + jestExpect(status).toEqual(200); +}; + /** * Require server license to successfully continue. * @return {Object} returns {license} on success or fail when no license @@ -147,6 +181,7 @@ export const apiRequireLicenseForFeature = async (key = '') => { /** * Upload server license with file expected at "/detox/e2e/support/fixtures/mattermost-license.txt" + * @return {Object} returns response */ export const apiUploadLicense = async () => { const absFilePath = path.resolve(__dirname, '../../support/fixtures/mattermost-license.txt'); @@ -158,6 +193,7 @@ export const apiUploadLicense = async () => { /** * Get client license. * If no license, try to upload if license file is available at "/support/fixtures/mattermost-license.txt". + * @return {Object} returns {license} on success or upload when no license or get updated license. */ async function getClientLicense() { const {license} = await apiGetClientLicense(); @@ -179,11 +215,13 @@ async function getClientLicense() { export const System = { apiCheckSystemHealth, - apiGetConfig, - apiUpdateConfig, + apiEmailTest, apiGetClientLicense, + apiGetConfig, apiRequireLicense, apiRequireLicenseForFeature, + apiRequireSMTPServer, + apiUpdateConfig, apiUploadLicense, }; diff --git a/detox/e2e/support/test_config.js b/detox/e2e/support/test_config.js index 22bdbdc75..f435c6cad 100644 --- a/detox/e2e/support/test_config.js +++ b/detox/e2e/support/test_config.js @@ -4,6 +4,8 @@ module.exports = { serverUrl: process.env.SITE_URL || (process.env.IOS ? 'http://localhost:8065' : 'http://10.0.2.2:8065'), siteUrl: process.env.SITE_URL || 'http://localhost:8065', + smtpUrl: process.env.SMTP_URL || 'http://localhost:10080', + adminEmail: process.env.ADMIN_EMAIL || 'sysadmin@sample.mattermost.com', adminUsername: process.env.ADMIN_USERNAME || 'sysadmin', adminPassword: process.env.ADMIN_PASSWORD || 'Sys@dmin-sample1', ldapServer: process.env.LDAP_SERVER || 'localhost', diff --git a/detox/e2e/support/ui/component/post.js b/detox/e2e/support/ui/component/post.js index 7f809570f..c68c634bf 100644 --- a/detox/e2e/support/ui/component/post.js +++ b/detox/e2e/support/ui/component/post.js @@ -4,6 +4,7 @@ class Post { testID = { postHeaderReply: 'post_header.reply', + postPreHeaderText: 'post_pre_header.text', markdownText: 'markdown_text', } @@ -12,11 +13,13 @@ class Post { const baseMatcher = by.id(postTestID); const postItemMatcher = postMessage ? baseMatcher.withDescendant(by.text(postMessage)) : baseMatcher; const postItemHeaderReplyMatcher = by.id(this.testID.postHeaderReply).withAncestor(postItemMatcher); + const postItemPreHeaderTextMatch = by.id(this.testID.postPreHeaderText).withAncestor(postItemMatcher); const postItemMessageMatcher = by.id(this.testID.markdownText).withAncestor(postItemMatcher); return { postItem: element(postItemMatcher), postItemHeaderReply: element(postItemHeaderReplyMatcher), + postItemPreHeaderText: element(postItemPreHeaderTextMatch), postItemMessage: element(postItemMessageMatcher), }; } diff --git a/detox/e2e/support/ui/component/post_list.js b/detox/e2e/support/ui/component/post_list.js index f923f1d06..e02896e0b 100644 --- a/detox/e2e/support/ui/component/post_list.js +++ b/detox/e2e/support/ui/component/post_list.js @@ -11,10 +11,17 @@ class PostList { } getPost = (postId, postMessage) => { - const {postItem, postItemHeaderReply, postItemMessage} = Post.getPost(this.testID.postListPostItem, postId, postMessage); + const { + postItem, + postItemHeaderReply, + postItemPreHeaderText, + postItemMessage, + } = Post.getPost(this.testID.postListPostItem, postId, postMessage); + return { postListPostItem: postItem, postListPostItemHeaderReply: postItemHeaderReply, + postListPostItemPreHeaderText: postItemPreHeaderText, postListPostItemMessage: postItemMessage, }; } diff --git a/detox/e2e/support/ui/screen/index.js b/detox/e2e/support/ui/screen/index.js index 7c7f67dee..c156642e3 100644 --- a/detox/e2e/support/ui/screen/index.js +++ b/detox/e2e/support/ui/screen/index.js @@ -14,6 +14,7 @@ import LongPostScreen from './long_post'; import MoreChannelsScreen from './more_channels'; import MoreDirectMessagesScreen from './more_direct_messages'; import NotificationScreen from './notification'; +import NotificationSettingsEmailScreen from './notification_settings_email'; import NotificationSettingsMobileScreen from './notification_settings_mobile'; import NotificationSettingsScreen from './notification_settings'; import PermalinkScreen from './permalink'; @@ -40,6 +41,7 @@ export { MoreChannelsScreen, MoreDirectMessagesScreen, NotificationScreen, + NotificationSettingsEmailScreen, NotificationSettingsMobileScreen, NotificationSettingsScreen, PermalinkScreen, diff --git a/detox/e2e/support/ui/screen/notification_settings.js b/detox/e2e/support/ui/screen/notification_settings.js index c5f2596e8..d07c9b6ad 100644 --- a/detox/e2e/support/ui/screen/notification_settings.js +++ b/detox/e2e/support/ui/screen/notification_settings.js @@ -7,11 +7,15 @@ class NotificationSettingsScreen { testID = { notificationSettingsScreen: 'notification_settings.screen', backButton: 'screen.back.button', + emailAction: 'notification_settings.email.action', + mentionsAndRepliesAction: 'notification_settings.mentions_replies.action', mobileAction: 'notification_settings.mobile.action', } notificationSettingsScreen = element(by.id(this.testID.notificationSettingsScreen)); backButton = element(by.id(this.testID.backButton)); + emailAction = element(by.id(this.testID.emailAction)); + mentionsAndRepliesAction = element(by.id(this.testID.mentionsAndRepliesAction)); mobileAction = element(by.id(this.testID.mobileAction)); toBeVisible = async () => { diff --git a/detox/e2e/support/ui/screen/notification_settings_email.js b/detox/e2e/support/ui/screen/notification_settings_email.js new file mode 100644 index 000000000..75ec718ab --- /dev/null +++ b/detox/e2e/support/ui/screen/notification_settings_email.js @@ -0,0 +1,70 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {NotificationSettingsScreen} from '@support/ui/screen'; + +class NotificationSettingsEmailScreen { + testID = { + notificationSettingsEmailScreen: 'notification_settings_email.screen', + backButton: 'screen.back.button', + immediatelyAction: 'notification_settings_email.immediately.action', + immediatelyActionSelected: 'notification_settings_email.immediately.action.selected', + neverAction: 'notification_settings_email.never.action', + neverActionSelected: 'notification_settings_email.never.action.selected', + + // ANDROID ONLY + sendAction: 'notification_settings_email.send.action', + sendActionDescription: 'notification_settings_email.send.action.description', + sendActionLabel: 'notification_settings_email.send.action.label', + sendModal: 'notification_settings_email.send.modal', + sendModalCancelButton: 'notification_settings_email.send_modal_cancel.button', + sendModalSaveButton: 'notification_settings_email.send_modal_save.button', + } + + notificationSettingsEmailScreen = element(by.id(this.testID.notificationSettingsEmailScreen)); + backButton = element(by.id(this.testID.backButton)); + immediatelyAction = element(by.id(this.testID.immediatelyAction)); + immediatelyActionSelected = element(by.id(this.testID.immediatelyActionSelected)); + neverAction = element(by.id(this.testID.neverAction)); + neverActionSelected = element(by.id(this.testID.neverActionSelected)); + + // ANDROID ONLY + sendAction = element(by.id(this.testID.sendAction)); + sendActionDescription = element(by.id(this.testID.sendActionDescription)); + sendActionLabel = element(by.id(this.testID.sendActionLabel)); + sendModal = element(by.id(this.testID.sendModal)); + sendModalCancelButton = element(by.id(this.testID.sendModalCancelButton)); + sendModalSaveButton = element(by.id(this.testID.sendModalSaveButton)); + + getSendActionFor = (sendKey) => { + switch (sendKey) { + case 'immediately': + return this.immediatelyAction; + case 'never': + return this.neverAction; + default: + throw new Error('Not a valid send option: ' + sendKey); + } + } + + toBeVisible = async () => { + await expect(this.notificationSettingsEmailScreen).toBeVisible(); + + return this.notificationSettingsEmailScreen; + } + + open = async () => { + // # Open notification settings email screen + await NotificationSettingsScreen.emailAction.tap(); + + return this.toBeVisible(); + } + + back = async () => { + await this.backButton.tap(); + await expect(this.notificationSettingsEmailScreen).not.toBeVisible(); + } +} + +const notificationSettingsEmailScreen = new NotificationSettingsEmailScreen(); +export default notificationSettingsEmailScreen; diff --git a/detox/e2e/support/utils.js b/detox/e2e/support/utils.js index 192e9bbd6..a4ddb6582 100644 --- a/detox/e2e/support/utils.js +++ b/detox/e2e/support/utils.js @@ -1,7 +1,9 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. +import axios from 'axios'; import {v4 as uuidv4} from 'uuid'; +import testConfig from '@support/test_config'; /** * Explicit `wait` should not normally used but made available for special cases. @@ -48,6 +50,59 @@ export const capitalize = (text) => { return text.charAt(0).toUpperCase() + text.slice(1); }; +/** + * Get admin account. + */ +export const getAdminAccount = () => { + return { + username: testConfig.adminUsername, + password: testConfig.adminPassword, + email: testConfig.adminEmail, + }; +}; + +/** + * Get recent email. + * @param {string} username - username of email recipient + * @param {string} mailUrl - url of email + */ +export const getRecentEmail = async (username, mailUrl = `${testConfig.smtpUrl}/api/v1/mailbox`) => { + const mailboxUrl = `${mailUrl}/${username}`; + let response; + let recentEmail; + + try { + response = await axios({url: mailboxUrl, method: 'get'}); + recentEmail = response.data[response.data.length - 1]; + } catch (error) { + return {status: error.status, data: null}; + } + + if (!recentEmail || !recentEmail.id) { + return {status: 501, data: null}; + } + + let recentEmailMessage; + const mailMessageUrl = `${mailboxUrl}/${recentEmail.id}`; + try { + response = await axios({url: mailMessageUrl, method: 'get'}); + recentEmailMessage = response.data; + } catch (error) { + return {status: error.status, data: null}; + } + + return {status: response.status, data: recentEmailMessage}; +}; + +/** + * Split email body text. + * @param {string} text + * @return {string} split text + */ +export function splitEmailBodyText(text) { + return text.split('\n').map((d) => d.trim()); +} + const SECOND = 1000; const MINUTE = 60 * 1000; diff --git a/detox/e2e/test/notifications/channel_notification_default.e2e.js b/detox/e2e/test/notifications/channel_notification_default.e2e.js index 10e49ab6f..185c326b9 100644 --- a/detox/e2e/test/notifications/channel_notification_default.e2e.js +++ b/detox/e2e/test/notifications/channel_notification_default.e2e.js @@ -91,6 +91,13 @@ describe('Channel Notification Preference - Default', () => { }); async function setGlobalNotificationsTo(pushKey) { + const { + getPushActionFor, + pushAction, + pushModal, + pushModalSaveButton, + } = NotificationSettingsMobileScreen; + // # Open notifications settings mobile screen await ChannelScreen.openSettingsSidebar(); await GeneralSettingsScreen.open(); @@ -99,16 +106,16 @@ async function setGlobalNotificationsTo(pushKey) { // # Tap on Send Notifications option if Android if (isAndroid()) { - await NotificationSettingsMobileScreen.pushAction.tap(); - await expect(NotificationSettingsMobileScreen.pushModal).toBeVisible(); + await pushAction.tap(); + await expect(pushModal).toBeVisible(); } // # Tap on push activity option - await NotificationSettingsMobileScreen.getPushActionFor(pushKey).tap(); + await getPushActionFor(pushKey).tap(); // # Tap on Save button if Android if (isAndroid()) { - await NotificationSettingsMobileScreen.pushModalSaveButton.tap(); + await pushModalSaveButton.tap(); } // # Navigate back to channel screen diff --git a/detox/e2e/test/smoke_test/direct_messages.e2e.js b/detox/e2e/test/smoke_test/direct_messages.e2e.js new file mode 100644 index 000000000..853901d79 --- /dev/null +++ b/detox/e2e/test/smoke_test/direct_messages.e2e.js @@ -0,0 +1,84 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +// ******************************************************************* +// - [#] indicates a test step (e.g. # Go to a screen) +// - [*] indicates an assertion (e.g. * Check the title) +// - Use element testID when selecting an element. Create one if none. +// ******************************************************************* + +import {MainSidebar} from '@support/ui/component'; +import { + ChannelInfoScreen, + ChannelScreen, + MoreDirectMessagesScreen, +} from '@support/ui/screen'; +import { + Channel, + Setup, + Team, + User, +} from '@support/server_api'; +import {getRandomId} from '@support/utils'; + +describe('Direct Messages', () => { + const searchTerm = getRandomId(); + let testUser; + let testOtherUser; + let townSquareChannel; + + beforeAll(async () => { + const {user, team} = await Setup.apiInit(); + testUser = user; + + ({user: testOtherUser} = await User.apiCreateUser({prefix: searchTerm})); + await Team.apiAddUserToTeam(testOtherUser.id, team.id); + + ({channel: townSquareChannel} = await Channel.apiGetChannelByName(team.name, 'town-square')); + + // # Open channel screen + await ChannelScreen.open(testUser); + }); + + afterAll(async () => { + await ChannelScreen.logout(); + }); + + it('MM-T3215 should be able to close direct message', async () => { + const { + channelNavBarTitle, + closeMainSidebar, + openMainSidebar, + } = ChannelScreen; + const { + getUserAtIndex, + searchInput, + startButton, + } = MoreDirectMessagesScreen; + const {getChannelByDisplayName} = MainSidebar; + + // # Create a DM with the other user + await openMainSidebar(); + await MoreDirectMessagesScreen.open(); + await searchInput.typeText(searchTerm); + await getUserAtIndex(0).tap(); + await startButton.tap(); + + // * Verify DM channel is created + await ChannelInfoScreen.open(); + await expect(ChannelInfoScreen.headerDisplayName).toHaveText(testOtherUser.username); + await ChannelInfoScreen.close(); + await openMainSidebar(); + await getChannelByDisplayName(testOtherUser.username).tap(); + + // # Close DM channel + await ChannelInfoScreen.open(); + await ChannelInfoScreen.leaveAction.tap(); + + // * Verify redirected to town square and does not appear in channel list + await expect(channelNavBarTitle).toHaveText(townSquareChannel.display_name); + await openMainSidebar(); + await expect(getChannelByDisplayName(testOtherUser.username)).not.toBeVisible(); + await closeMainSidebar(); + }); +}); diff --git a/detox/e2e/test/smoke_test/email_notifications.e2e.js b/detox/e2e/test/smoke_test/email_notifications.e2e.js new file mode 100644 index 000000000..33d39bc25 --- /dev/null +++ b/detox/e2e/test/smoke_test/email_notifications.e2e.js @@ -0,0 +1,227 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +// ******************************************************************* +// - [#] indicates a test step (e.g. # Go to a screen) +// - [*] indicates an assertion (e.g. * Check the title) +// - Use element testID when selecting an element. Create one if none. +// ******************************************************************* + +import jestExpect from 'expect'; + +import { + ChannelScreen, + GeneralSettingsScreen, + NotificationSettingsEmailScreen, + NotificationSettingsScreen, +} from '@support/ui/screen'; +import { + Channel, + Post, + Setup, + Status, + System, + Team, + User, +} from '@support/server_api'; +import { + capitalize, + getRecentEmail, + isAndroid, + splitEmailBodyText, +} from '@support/utils'; + +describe('Email Notifications', () => { + let testUser; + let testOtherUser1; + let testOtherUser2; + let testTeam; + let testChannel; + let testConfig; + + beforeAll(async () => { + await System.apiRequireSMTPServer(); + + const {team, user} = await Setup.apiInit(); + testUser = user; + testTeam = team; + + await Status.apiUpdateUserStatus(testUser.id, 'offline'); + + const {channel} = await Channel.apiGetChannelByName(team.name, 'town-square'); + testChannel = channel; + + ({user: testOtherUser1} = await User.apiCreateUser()); + await Team.apiAddUserToTeam(testOtherUser1.id, testTeam.id); + + ({user: testOtherUser2} = await User.apiCreateUser()); + await Team.apiAddUserToTeam(testOtherUser2.id, testTeam.id); + + ({config: testConfig} = await System.apiUpdateConfig({EmailSettings: {SendEmailNotifications: true}})); + + // # Open channel screen + await ChannelScreen.open(testUser); + }); + + afterAll(async () => { + await ChannelScreen.logout(); + }); + + it('MM-T3256_1 should be able to change email notification setting to immediately', async () => { + // # Set global notifications to immediately + await setEmailNotificationsTo('immediately'); + + // * Verify email notifications is set to immediately + await openEmailNotificationsSettings(); + await verifyEmailNotificationsIsSetTo('immediately'); + await navigateBackToChannel(); + + // # Post an at-mention message to mentioned user by other user + const message = `Mention @${testUser.username} by ${testOtherUser1.username}`; + await User.apiLogin(testOtherUser1); + await Post.apiCreatePost({ + channelId: testChannel.id, + message, + }); + + // * Verify mentioned user receives email notification + const response = await getRecentEmail(testUser.username); + verifyEmailNotification( + response, + testConfig.TeamSettings.SiteName, + testTeam.display_name, + testChannel.display_name, + testUser, + testOtherUser1, + message, + testConfig.EmailSettings.FeedbackEmail, + testConfig.SupportSettings.SupportEmail); + }); + + it('MM-T3256_2 should be able to change email notification setting to never', async () => { + // # Set global notifications to never + await setEmailNotificationsTo('never'); + + // * Verify email notifications is set to never + await openEmailNotificationsSettings(); + await verifyEmailNotificationsIsSetTo('never'); + await navigateBackToChannel(); + + // # Post an at-mention message to mentioned user by other user + const message = `Mention @${testUser.username} by ${testOtherUser2.username}`; + await User.apiLogin(testOtherUser2); + await Post.apiCreatePost({ + channelId: testChannel.id, + message, + }); + + // * Verify mentioned user does not receive email notification + const {data} = await getRecentEmail(testUser.username); + const bodyText = splitEmailBodyText(data.body.text); + jestExpect(bodyText[7]).not.toEqual(message); + }); +}); + +async function openEmailNotificationsSettings() { + // # Open notifications settings email screen + await ChannelScreen.openSettingsSidebar(); + await GeneralSettingsScreen.open(); + await NotificationSettingsScreen.open(); + await NotificationSettingsEmailScreen.open(); +} + +async function navigateBackToChannel() { + // # Navigate back to channel screen + await NotificationSettingsEmailScreen.toBeVisible(); + await NotificationSettingsEmailScreen.back(); + await NotificationSettingsScreen.back(); + await GeneralSettingsScreen.close(); +} + +async function setEmailNotificationsTo(sendKey) { + const { + getSendActionFor, + sendAction, + sendModal, + sendModalSaveButton, + } = NotificationSettingsEmailScreen; + + // # Open email notifications settings + await openEmailNotificationsSettings(); + + // # Tap on Send email notifications option if Android + if (isAndroid()) { + await sendAction.tap(); + await expect(sendModal).toBeVisible(); + } + + // # Tap on send activity option + await getSendActionFor(sendKey).tap(); + + // # Tap on Save button if Android + if (isAndroid()) { + await sendModalSaveButton.tap(); + } + + // # Navigate back to channel + await navigateBackToChannel(); +} + +async function verifyEmailNotificationsIsSetTo(sendKey) { + const { + immediatelyActionSelected, + neverActionSelected, + sendActionDescription, + } = NotificationSettingsEmailScreen; + + if (isAndroid()) { + await expect(sendActionDescription).toHaveText(capitalize(sendKey)); + } else { + switch (sendKey) { + case 'immediately': + await expect(immediatelyActionSelected).toBeVisible(); + await expect(neverActionSelected).not.toBeVisible(); + break; + case 'never': + await expect(neverActionSelected).toBeVisible(); + await expect(immediatelyActionSelected).not.toBeVisible(); + break; + default: + throw new Error('Not a valid send option: ' + sendKey); + } + } +} + +function verifyEmailNotification(response, siteName, teamDisplayName, channelDisplayName, mentionedUser, byUser, message, feedbackEmail, supportEmail) { + const isoDate = new Date().toISOString().substring(0, 10); + const {data, status} = response; + + // * Should return success status + jestExpect(status).toEqual(200); + + // * Verify that email is addressed to mentionedUser + jestExpect(data.to.length).toEqual(1); + jestExpect(data.to[0]).toContain(mentionedUser.email); + + // * Verify that email is from default feedback email + jestExpect(data.from).toContain(feedbackEmail); + + // * Verify that date is current + jestExpect(data.date).toContain(isoDate); + + // * Verify that the email subject is correct + jestExpect(data.subject).toContain(`[${siteName}] Notification in ${teamDisplayName}`); + + // * Verify that the email body is correct + const bodyText = splitEmailBodyText(data.body.text); + jestExpect(bodyText.length).toEqual(16); + jestExpect(bodyText[1]).toEqual('You have a new notification.'); + jestExpect(bodyText[4]).toEqual(`Channel: ${channelDisplayName}`); + jestExpect(bodyText[5]).toContain(`@${byUser.username}`); + jestExpect(bodyText[7]).toEqual(message); + jestExpect(bodyText[9]).toContain('Go To Post'); + jestExpect(bodyText[11]).toEqual(`Any questions at all, mail us any time: ${supportEmail}`); + jestExpect(bodyText[12]).toEqual('Best wishes,'); + jestExpect(bodyText[13]).toEqual(`The ${siteName} Team`); + jestExpect(bodyText[15]).toEqual('To change your notification preferences, log in to your team site and go to Account Settings > Notifications.'); +} diff --git a/detox/e2e/test/smoke_test/favorite_channels.e2e.js b/detox/e2e/test/smoke_test/favorite_channels.e2e.js index 0ab640b09..c9aa1b9ff 100644 --- a/detox/e2e/test/smoke_test/favorite_channels.e2e.js +++ b/detox/e2e/test/smoke_test/favorite_channels.e2e.js @@ -15,6 +15,18 @@ import { import {Setup} from '@support/server_api'; describe('Favorite Channels', () => { + const { + closeMainSidebar, + openMainSidebar, + } = ChannelScreen; + const { + favoriteSwitchFalse, + favoriteSwitchTrue, + } = ChannelInfoScreen; + const { + getChannelByDisplayName, + hasChannelDisplayNameAtIndex, + } = MainSidebar; let testChannel; beforeAll(async () => { @@ -30,19 +42,6 @@ describe('Favorite Channels', () => { }); it('MM-T3191 should be able to favorite a channel', async () => { - const { - closeMainSidebar, - openMainSidebar, - } = ChannelScreen; - const { - favoriteSwitchFalse, - favoriteSwitchTrue, - } = ChannelInfoScreen; - const { - getChannelByDisplayName, - hasChannelDisplayNameAtIndex, - } = MainSidebar; - // # Open channel info screen await openMainSidebar(); await getChannelByDisplayName(testChannel.display_name).tap(); @@ -68,4 +67,31 @@ describe('Favorite Channels', () => { // # Close main sidebar await closeMainSidebar(); }); + + it('MM-T3192 should be able to un-favorite a channel', async () => { + // # Open channel info screen + await openMainSidebar(); + await getChannelByDisplayName(testChannel.display_name).tap(); + await ChannelInfoScreen.open(); + + // * Verify favorite switch is toggled on + await expect(favoriteSwitchTrue).toBeVisible(); + await expect(favoriteSwitchFalse).not.toBeVisible(); + + // # Toggle off favorite switch + await favoriteSwitchTrue.tap(); + + // * Verify favorite switch is toggled off + await expect(favoriteSwitchFalse).toBeVisible(); + await expect(favoriteSwitchTrue).not.toBeVisible(); + + // * Verify channel does not appear in favorite channels list + await ChannelInfoScreen.close(); + await openMainSidebar(); + await expect(element(by.text('FAVORITE CHANNELS'))).not.toBeVisible(); + await hasChannelDisplayNameAtIndex(0, testChannel.display_name); + + // # Close main sidebar + await closeMainSidebar(); + }); }); diff --git a/detox/e2e/test/smoke_test/group_message_channel.e2e.js b/detox/e2e/test/smoke_test/group_messages.e2e.js similarity index 98% rename from detox/e2e/test/smoke_test/group_message_channel.e2e.js rename to detox/e2e/test/smoke_test/group_messages.e2e.js index 74faf2521..54bba11d5 100644 --- a/detox/e2e/test/smoke_test/group_message_channel.e2e.js +++ b/detox/e2e/test/smoke_test/group_messages.e2e.js @@ -19,7 +19,7 @@ import { } from '@support/server_api'; import {getRandomId} from '@support/utils'; -describe('Group Message Channel', () => { +describe('Group Messages', () => { const searchTerm = getRandomId(); let testUser; let testOtherUser1; diff --git a/detox/e2e/test/smoke_test/saved_messages.e2e.js b/detox/e2e/test/smoke_test/saved_messages.e2e.js new file mode 100644 index 000000000..f60f8d8b6 --- /dev/null +++ b/detox/e2e/test/smoke_test/saved_messages.e2e.js @@ -0,0 +1,90 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +// ******************************************************************* +// - [#] indicates a test step (e.g. # Go to a screen) +// - [*] indicates an assertion (e.g. * Check the title) +// - Use element testID when selecting an element. Create one if none. +// ******************************************************************* + +import {PostOptions} from '@support/ui/component'; +import { + ChannelScreen, + SavedMessagesScreen, + ThreadScreen, +} from '@support/ui/screen'; +import { + Channel, + Post, + Setup, +} from '@support/server_api'; + +describe('Saved Messages', () => { + const { + getPostListPostItem, + openPostOptionsFor, + openReplyThreadFor, + openSettingsSidebar, + postMessage, + } = ChannelScreen; + const { + saveAction, + unsaveAction, + } = PostOptions; + const message = Date.now().toString(); + let testChannel; + + beforeAll(async () => { + const {team, user} = await Setup.apiInit(); + + const {channel} = await Channel.apiGetChannelByName(team.name, 'town-square'); + testChannel = channel; + + // # Open channel screen + await ChannelScreen.open(user); + }); + + afterAll(async () => { + await ChannelScreen.logout(); + }); + + it('MM-T3219 should be able save a message from channel post list', async () => { + // # Post a message + await postMessage(message); + + // # Save message from channel post list + const {post} = await Post.apiGetLastPostInChannel(testChannel.id); + await openPostOptionsFor(post.id, message); + await saveAction.tap(); + + // * Verify message appears in saved messages + const {postListPostItemPreHeaderText} = await getPostListPostItem(post.id, message); + await expect(postListPostItemPreHeaderText).toHaveText('Saved'); + await openSettingsSidebar(); + await SavedMessagesScreen.open(); + const {searchResultPostItem} = await SavedMessagesScreen.getSearchResultPostItem(post.id, message); + await expect(searchResultPostItem).toBeVisible(); + + // # Close saved messages screen + await SavedMessagesScreen.close(); + }); + + it('MM-T3221 should be able unsave from reply thread', async () => { + // # Unsave message from reply thread + const {post} = await Post.apiGetLastPostInChannel(testChannel.id); + await openReplyThreadFor(post.id, message); + await ThreadScreen.openPostOptionsFor(post.id, message); + await unsaveAction.tap(); + + // * Verify message does not appear in saved messages + const {postListPostItemPreHeaderText} = await getPostListPostItem(post.id, message); + await expect(postListPostItemPreHeaderText).not.toBeVisible(); + await ThreadScreen.back(); + await openSettingsSidebar(); + await SavedMessagesScreen.open(); + await expect(element(by.text('No Saved messages yet'))).toBeVisible(); + + // # Close saved messages screen + await SavedMessagesScreen.close(); + }); +}); diff --git a/detox/package-lock.json b/detox/package-lock.json index 9e4070b54..990f1efa1 100644 --- a/detox/package-lock.json +++ b/detox/package-lock.json @@ -69,9 +69,9 @@ "dev": true }, "@babel/types": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", - "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.17.tgz", + "integrity": "sha512-tNMDjcv/4DIcHxErTgwB9q2ZcYyN0sUfgGKUK/mm1FJK7Wz+KstoEekxrl/tBiNDgLK1HGi+sppj1An/1DR4fQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", @@ -98,9 +98,9 @@ "dev": true }, "@babel/types": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", - "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.17.tgz", + "integrity": "sha512-tNMDjcv/4DIcHxErTgwB9q2ZcYyN0sUfgGKUK/mm1FJK7Wz+KstoEekxrl/tBiNDgLK1HGi+sppj1An/1DR4fQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", @@ -111,13 +111,13 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.13.tgz", - "integrity": "sha512-dXof20y/6wB5HnLOGyLh/gobsMvDNoekcC+8MCV2iaTd5JemhFkPD73QB+tK3iFC9P0xJC73B6MvKkyUfS9cCw==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.17.tgz", + "integrity": "sha512-5EkibqLVYOuZ89BSg2lv+GG8feywLuvMXNYgf0Im4MssE0mFWPztSpJbildNnUgw0bLI2EsIN4MpSHC2iUJkQA==", "dev": true, "requires": { "@babel/compat-data": "^7.12.13", - "@babel/helper-validator-option": "^7.12.11", + "@babel/helper-validator-option": "^7.12.17", "browserslist": "^4.14.5", "semver": "^5.5.0" } @@ -279,9 +279,9 @@ } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.13.tgz", - "integrity": "sha512-XC+kiA0J3at6E85dL5UnCYfVOcIZ834QcAY0TIpgUVnz0zDzg+0TtvZTnJ4g9L1dPRGe30Qi03XCIS4tYCLtqw==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.17.tgz", + "integrity": "sha512-p2VGmBu9oefLZ2nQpgnEnG0ZlRPvL8gAGvPUMQwUdaE8k49rOMuZpOwdQoy5qJf6K8jL3bcAMhVUlHAjIgJHUg==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.12.13", @@ -304,9 +304,9 @@ "dev": true }, "@babel/types": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", - "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.17.tgz", + "integrity": "sha512-tNMDjcv/4DIcHxErTgwB9q2ZcYyN0sUfgGKUK/mm1FJK7Wz+KstoEekxrl/tBiNDgLK1HGi+sppj1An/1DR4fQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", @@ -352,9 +352,9 @@ "dev": true }, "@babel/types": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", - "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.17.tgz", + "integrity": "sha512-tNMDjcv/4DIcHxErTgwB9q2ZcYyN0sUfgGKUK/mm1FJK7Wz+KstoEekxrl/tBiNDgLK1HGi+sppj1An/1DR4fQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", @@ -432,9 +432,9 @@ "dev": true }, "@babel/types": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", - "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.17.tgz", + "integrity": "sha512-tNMDjcv/4DIcHxErTgwB9q2ZcYyN0sUfgGKUK/mm1FJK7Wz+KstoEekxrl/tBiNDgLK1HGi+sppj1An/1DR4fQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", @@ -490,9 +490,9 @@ "dev": true }, "@babel/helper-validator-option": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.11.tgz", - "integrity": "sha512-TBFCyj939mFSdeX7U7DDj32WtzYY7fDcalgq8v3fBZMNOJQNn7nOYzMaUCiPxPYfCup69mtIpqlKgMZLvQ8Xhw==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", + "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", "dev": true }, "@babel/helper-wrap-function": { @@ -517,12 +517,12 @@ } }, "@babel/generator": { - "version": "7.12.15", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz", - "integrity": "sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.17.tgz", + "integrity": "sha512-DSA7ruZrY4WI8VxuS1jWSRezFnghEoYEFrZcw9BizQRmOZiUsiHl59+qEARGPqPikwA/GPTyRCi7isuCK/oyqg==", "dev": true, "requires": { - "@babel/types": "^7.12.13", + "@babel/types": "^7.12.17", "jsesc": "^2.5.1", "source-map": "^0.5.0" } @@ -574,9 +574,9 @@ } }, "@babel/parser": { - "version": "7.12.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.15.tgz", - "integrity": "sha512-AQBOU2Z9kWwSZMd6lNjCX0GUgFonL1wAM1db8L8PMk9UDaGsRCArBkU4Sc+UCM3AE4hjbXx+h58Lb3QT4oRmrA==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.17.tgz", + "integrity": "sha512-r1yKkiUTYMQ8LiEI0UcQx5ETw5dpTLn9wijn9hk6KkTtOK95FndDN10M+8/s6k/Ymlbivw0Av9q4SlgF80PtHg==", "dev": true }, "@babel/template": { @@ -591,26 +591,26 @@ } }, "@babel/traverse": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.13.tgz", - "integrity": "sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.17.tgz", + "integrity": "sha512-LGkTqDqdiwC6Q7fWSwQoas/oyiEYw6Hqjve5KOSykXkmFJFqzvGMb9niaUEag3Rlve492Mkye3gLw9FTv94fdQ==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.12.13", + "@babel/generator": "^7.12.17", "@babel/helper-function-name": "^7.12.13", "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13", + "@babel/parser": "^7.12.17", + "@babel/types": "^7.12.17", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", - "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.17.tgz", + "integrity": "sha512-tNMDjcv/4DIcHxErTgwB9q2ZcYyN0sUfgGKUK/mm1FJK7Wz+KstoEekxrl/tBiNDgLK1HGi+sppj1An/1DR4fQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", @@ -733,13 +733,21 @@ } }, "@babel/plugin-proposal-dynamic-import": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.1.tgz", - "integrity": "sha512-a4rhUSZFuq5W8/OO8H7BL5zspjnc1FLd9hlOxIK/f7qG4a0qsqk8uvF/ywgBA8/OmjsapjpvaEOYItfGG1qIvQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.17.tgz", + "integrity": "sha512-ZNGoFZqrnuy9H2izB2jLlnNDAfVPlGl5NhFEiFe4D84ix9GQGygF+CWMGHKuE+bpyS/AOuDQCnkiRNqW2IzS1Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.12.13", "@babel/plugin-syntax-dynamic-import": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.12.13.tgz", + "integrity": "sha512-C+10MXCXJLiR6IeG9+Wiejt9jmtFpxUc3MQqCmPY8hfCjyUGl9kT+B2okzEZrtykiwrc4dbCPdDoz0A/HQbDaA==", + "dev": true + } } }, "@babel/plugin-proposal-export-namespace-from": { @@ -870,9 +878,9 @@ } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.13.tgz", - "integrity": "sha512-0ZwjGfTcnZqyV3y9DSD1Yk3ebp+sIUpT2YDqP8hovzaNZnQq2Kd7PEqa6iOIUDBXBt7Jl3P7YAcEIL5Pz8u09Q==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.17.tgz", + "integrity": "sha512-TvxwI80pWftrGPKHNfkvX/HnoeSTR7gC4ezWnAL39PuktYUe6r8kEpOLTYnkBTsaoeazXm2jHJ22EQ81sdgfcA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.12.13", @@ -1100,9 +1108,9 @@ "dev": true }, "@babel/types": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", - "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.17.tgz", + "integrity": "sha512-tNMDjcv/4DIcHxErTgwB9q2ZcYyN0sUfgGKUK/mm1FJK7Wz+KstoEekxrl/tBiNDgLK1HGi+sppj1An/1DR4fQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", @@ -1171,12 +1179,12 @@ } }, "@babel/generator": { - "version": "7.12.15", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz", - "integrity": "sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.17.tgz", + "integrity": "sha512-DSA7ruZrY4WI8VxuS1jWSRezFnghEoYEFrZcw9BizQRmOZiUsiHl59+qEARGPqPikwA/GPTyRCi7isuCK/oyqg==", "dev": true, "requires": { - "@babel/types": "^7.12.13", + "@babel/types": "^7.12.17", "jsesc": "^2.5.1", "source-map": "^0.5.0" } @@ -1202,12 +1210,12 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.13.tgz", - "integrity": "sha512-B+7nN0gIL8FZ8SvMcF+EPyB21KnCcZHQZFczCxbiNGV/O0rsrSBlWGLzmtBJ3GMjSVMIm4lpFhR+VdVBuIsUcQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.17.tgz", + "integrity": "sha512-Bzv4p3ODgS/qpBE0DiJ9qf5WxSmrQ8gVTe8ClMfwwsY2x/rhykxxy3bXzG7AGTnPB2ij37zGJ/Q/6FruxHxsxg==", "dev": true, "requires": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.12.17" } }, "@babel/helper-optimise-call-expression": { @@ -1264,9 +1272,9 @@ } }, "@babel/parser": { - "version": "7.12.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.15.tgz", - "integrity": "sha512-AQBOU2Z9kWwSZMd6lNjCX0GUgFonL1wAM1db8L8PMk9UDaGsRCArBkU4Sc+UCM3AE4hjbXx+h58Lb3QT4oRmrA==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.17.tgz", + "integrity": "sha512-r1yKkiUTYMQ8LiEI0UcQx5ETw5dpTLn9wijn9hk6KkTtOK95FndDN10M+8/s6k/Ymlbivw0Av9q4SlgF80PtHg==", "dev": true }, "@babel/template": { @@ -1281,26 +1289,26 @@ } }, "@babel/traverse": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.13.tgz", - "integrity": "sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.17.tgz", + "integrity": "sha512-LGkTqDqdiwC6Q7fWSwQoas/oyiEYw6Hqjve5KOSykXkmFJFqzvGMb9niaUEag3Rlve492Mkye3gLw9FTv94fdQ==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.12.13", + "@babel/generator": "^7.12.17", "@babel/helper-function-name": "^7.12.13", "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13", + "@babel/parser": "^7.12.17", + "@babel/types": "^7.12.17", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", - "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.17.tgz", + "integrity": "sha512-tNMDjcv/4DIcHxErTgwB9q2ZcYyN0sUfgGKUK/mm1FJK7Wz+KstoEekxrl/tBiNDgLK1HGi+sppj1An/1DR4fQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", @@ -1477,9 +1485,9 @@ } }, "@babel/parser": { - "version": "7.12.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.15.tgz", - "integrity": "sha512-AQBOU2Z9kWwSZMd6lNjCX0GUgFonL1wAM1db8L8PMk9UDaGsRCArBkU4Sc+UCM3AE4hjbXx+h58Lb3QT4oRmrA==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.17.tgz", + "integrity": "sha512-r1yKkiUTYMQ8LiEI0UcQx5ETw5dpTLn9wijn9hk6KkTtOK95FndDN10M+8/s6k/Ymlbivw0Av9q4SlgF80PtHg==", "dev": true }, "@babel/template": { @@ -1494,9 +1502,9 @@ } }, "@babel/types": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", - "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.17.tgz", + "integrity": "sha512-tNMDjcv/4DIcHxErTgwB9q2ZcYyN0sUfgGKUK/mm1FJK7Wz+KstoEekxrl/tBiNDgLK1HGi+sppj1An/1DR4fQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", @@ -1561,12 +1569,12 @@ } }, "@babel/generator": { - "version": "7.12.15", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz", - "integrity": "sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.17.tgz", + "integrity": "sha512-DSA7ruZrY4WI8VxuS1jWSRezFnghEoYEFrZcw9BizQRmOZiUsiHl59+qEARGPqPikwA/GPTyRCi7isuCK/oyqg==", "dev": true, "requires": { - "@babel/types": "^7.12.13", + "@babel/types": "^7.12.17", "jsesc": "^2.5.1", "source-map": "^0.5.0" } @@ -1592,12 +1600,12 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.13.tgz", - "integrity": "sha512-B+7nN0gIL8FZ8SvMcF+EPyB21KnCcZHQZFczCxbiNGV/O0rsrSBlWGLzmtBJ3GMjSVMIm4lpFhR+VdVBuIsUcQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.17.tgz", + "integrity": "sha512-Bzv4p3ODgS/qpBE0DiJ9qf5WxSmrQ8gVTe8ClMfwwsY2x/rhykxxy3bXzG7AGTnPB2ij37zGJ/Q/6FruxHxsxg==", "dev": true, "requires": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.12.17" } }, "@babel/helper-module-imports": { @@ -1610,9 +1618,9 @@ } }, "@babel/helper-module-transforms": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.13.tgz", - "integrity": "sha512-acKF7EjqOR67ASIlDTupwkKM1eUisNAjaSduo5Cz+793ikfnpe7p4Q7B7EWU2PCoSTPWsQkR7hRUWEIZPiVLGA==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.17.tgz", + "integrity": "sha512-sFL+p6zOCQMm9vilo06M4VHuTxUAwa6IxgL56Tq1DVtA0ziAGTH1ThmJq7xwPqdQlgAbKX3fb0oZNbtRIyA5KQ==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.12.13", @@ -1621,8 +1629,8 @@ "@babel/helper-split-export-declaration": "^7.12.13", "@babel/helper-validator-identifier": "^7.12.11", "@babel/template": "^7.12.13", - "@babel/traverse": "^7.12.13", - "@babel/types": "^7.12.13", + "@babel/traverse": "^7.12.17", + "@babel/types": "^7.12.17", "lodash": "^4.17.19" } }, @@ -1689,9 +1697,9 @@ } }, "@babel/parser": { - "version": "7.12.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.15.tgz", - "integrity": "sha512-AQBOU2Z9kWwSZMd6lNjCX0GUgFonL1wAM1db8L8PMk9UDaGsRCArBkU4Sc+UCM3AE4hjbXx+h58Lb3QT4oRmrA==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.17.tgz", + "integrity": "sha512-r1yKkiUTYMQ8LiEI0UcQx5ETw5dpTLn9wijn9hk6KkTtOK95FndDN10M+8/s6k/Ymlbivw0Av9q4SlgF80PtHg==", "dev": true }, "@babel/template": { @@ -1706,26 +1714,26 @@ } }, "@babel/traverse": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.13.tgz", - "integrity": "sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.17.tgz", + "integrity": "sha512-LGkTqDqdiwC6Q7fWSwQoas/oyiEYw6Hqjve5KOSykXkmFJFqzvGMb9niaUEag3Rlve492Mkye3gLw9FTv94fdQ==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.12.13", + "@babel/generator": "^7.12.17", "@babel/helper-function-name": "^7.12.13", "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13", + "@babel/parser": "^7.12.17", + "@babel/types": "^7.12.17", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", - "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.17.tgz", + "integrity": "sha512-tNMDjcv/4DIcHxErTgwB9q2ZcYyN0sUfgGKUK/mm1FJK7Wz+KstoEekxrl/tBiNDgLK1HGi+sppj1An/1DR4fQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", @@ -1954,12 +1962,12 @@ } }, "@babel/generator": { - "version": "7.12.15", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz", - "integrity": "sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.17.tgz", + "integrity": "sha512-DSA7ruZrY4WI8VxuS1jWSRezFnghEoYEFrZcw9BizQRmOZiUsiHl59+qEARGPqPikwA/GPTyRCi7isuCK/oyqg==", "dev": true, "requires": { - "@babel/types": "^7.12.13", + "@babel/types": "^7.12.17", "jsesc": "^2.5.1", "source-map": "^0.5.0" } @@ -1985,12 +1993,12 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.13.tgz", - "integrity": "sha512-B+7nN0gIL8FZ8SvMcF+EPyB21KnCcZHQZFczCxbiNGV/O0rsrSBlWGLzmtBJ3GMjSVMIm4lpFhR+VdVBuIsUcQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.17.tgz", + "integrity": "sha512-Bzv4p3ODgS/qpBE0DiJ9qf5WxSmrQ8gVTe8ClMfwwsY2x/rhykxxy3bXzG7AGTnPB2ij37zGJ/Q/6FruxHxsxg==", "dev": true, "requires": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.12.17" } }, "@babel/helper-module-imports": { @@ -2003,9 +2011,9 @@ } }, "@babel/helper-module-transforms": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.13.tgz", - "integrity": "sha512-acKF7EjqOR67ASIlDTupwkKM1eUisNAjaSduo5Cz+793ikfnpe7p4Q7B7EWU2PCoSTPWsQkR7hRUWEIZPiVLGA==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.17.tgz", + "integrity": "sha512-sFL+p6zOCQMm9vilo06M4VHuTxUAwa6IxgL56Tq1DVtA0ziAGTH1ThmJq7xwPqdQlgAbKX3fb0oZNbtRIyA5KQ==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.12.13", @@ -2014,8 +2022,8 @@ "@babel/helper-split-export-declaration": "^7.12.13", "@babel/helper-validator-identifier": "^7.12.11", "@babel/template": "^7.12.13", - "@babel/traverse": "^7.12.13", - "@babel/types": "^7.12.13", + "@babel/traverse": "^7.12.17", + "@babel/types": "^7.12.17", "lodash": "^4.17.19" } }, @@ -2082,9 +2090,9 @@ } }, "@babel/parser": { - "version": "7.12.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.15.tgz", - "integrity": "sha512-AQBOU2Z9kWwSZMd6lNjCX0GUgFonL1wAM1db8L8PMk9UDaGsRCArBkU4Sc+UCM3AE4hjbXx+h58Lb3QT4oRmrA==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.17.tgz", + "integrity": "sha512-r1yKkiUTYMQ8LiEI0UcQx5ETw5dpTLn9wijn9hk6KkTtOK95FndDN10M+8/s6k/Ymlbivw0Av9q4SlgF80PtHg==", "dev": true }, "@babel/template": { @@ -2099,26 +2107,26 @@ } }, "@babel/traverse": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.13.tgz", - "integrity": "sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.17.tgz", + "integrity": "sha512-LGkTqDqdiwC6Q7fWSwQoas/oyiEYw6Hqjve5KOSykXkmFJFqzvGMb9niaUEag3Rlve492Mkye3gLw9FTv94fdQ==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.12.13", + "@babel/generator": "^7.12.17", "@babel/helper-function-name": "^7.12.13", "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13", + "@babel/parser": "^7.12.17", + "@babel/types": "^7.12.17", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", - "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.17.tgz", + "integrity": "sha512-tNMDjcv/4DIcHxErTgwB9q2ZcYyN0sUfgGKUK/mm1FJK7Wz+KstoEekxrl/tBiNDgLK1HGi+sppj1An/1DR4fQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", @@ -2148,12 +2156,12 @@ } }, "@babel/generator": { - "version": "7.12.15", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz", - "integrity": "sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.17.tgz", + "integrity": "sha512-DSA7ruZrY4WI8VxuS1jWSRezFnghEoYEFrZcw9BizQRmOZiUsiHl59+qEARGPqPikwA/GPTyRCi7isuCK/oyqg==", "dev": true, "requires": { - "@babel/types": "^7.12.13", + "@babel/types": "^7.12.17", "jsesc": "^2.5.1", "source-map": "^0.5.0" } @@ -2179,12 +2187,12 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.13.tgz", - "integrity": "sha512-B+7nN0gIL8FZ8SvMcF+EPyB21KnCcZHQZFczCxbiNGV/O0rsrSBlWGLzmtBJ3GMjSVMIm4lpFhR+VdVBuIsUcQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.17.tgz", + "integrity": "sha512-Bzv4p3ODgS/qpBE0DiJ9qf5WxSmrQ8gVTe8ClMfwwsY2x/rhykxxy3bXzG7AGTnPB2ij37zGJ/Q/6FruxHxsxg==", "dev": true, "requires": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.12.17" } }, "@babel/helper-module-imports": { @@ -2197,9 +2205,9 @@ } }, "@babel/helper-module-transforms": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.13.tgz", - "integrity": "sha512-acKF7EjqOR67ASIlDTupwkKM1eUisNAjaSduo5Cz+793ikfnpe7p4Q7B7EWU2PCoSTPWsQkR7hRUWEIZPiVLGA==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.17.tgz", + "integrity": "sha512-sFL+p6zOCQMm9vilo06M4VHuTxUAwa6IxgL56Tq1DVtA0ziAGTH1ThmJq7xwPqdQlgAbKX3fb0oZNbtRIyA5KQ==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.12.13", @@ -2208,8 +2216,8 @@ "@babel/helper-split-export-declaration": "^7.12.13", "@babel/helper-validator-identifier": "^7.12.11", "@babel/template": "^7.12.13", - "@babel/traverse": "^7.12.13", - "@babel/types": "^7.12.13", + "@babel/traverse": "^7.12.17", + "@babel/types": "^7.12.17", "lodash": "^4.17.19" } }, @@ -2276,9 +2284,9 @@ } }, "@babel/parser": { - "version": "7.12.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.15.tgz", - "integrity": "sha512-AQBOU2Z9kWwSZMd6lNjCX0GUgFonL1wAM1db8L8PMk9UDaGsRCArBkU4Sc+UCM3AE4hjbXx+h58Lb3QT4oRmrA==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.17.tgz", + "integrity": "sha512-r1yKkiUTYMQ8LiEI0UcQx5ETw5dpTLn9wijn9hk6KkTtOK95FndDN10M+8/s6k/Ymlbivw0Av9q4SlgF80PtHg==", "dev": true }, "@babel/template": { @@ -2293,26 +2301,26 @@ } }, "@babel/traverse": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.13.tgz", - "integrity": "sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.17.tgz", + "integrity": "sha512-LGkTqDqdiwC6Q7fWSwQoas/oyiEYw6Hqjve5KOSykXkmFJFqzvGMb9niaUEag3Rlve492Mkye3gLw9FTv94fdQ==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.12.13", + "@babel/generator": "^7.12.17", "@babel/helper-function-name": "^7.12.13", "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13", + "@babel/parser": "^7.12.17", + "@babel/types": "^7.12.17", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", - "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.17.tgz", + "integrity": "sha512-tNMDjcv/4DIcHxErTgwB9q2ZcYyN0sUfgGKUK/mm1FJK7Wz+KstoEekxrl/tBiNDgLK1HGi+sppj1An/1DR4fQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", @@ -2368,12 +2376,12 @@ } }, "@babel/generator": { - "version": "7.12.15", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz", - "integrity": "sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.17.tgz", + "integrity": "sha512-DSA7ruZrY4WI8VxuS1jWSRezFnghEoYEFrZcw9BizQRmOZiUsiHl59+qEARGPqPikwA/GPTyRCi7isuCK/oyqg==", "dev": true, "requires": { - "@babel/types": "^7.12.13", + "@babel/types": "^7.12.17", "jsesc": "^2.5.1", "source-map": "^0.5.0" } @@ -2399,12 +2407,12 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.13.tgz", - "integrity": "sha512-B+7nN0gIL8FZ8SvMcF+EPyB21KnCcZHQZFczCxbiNGV/O0rsrSBlWGLzmtBJ3GMjSVMIm4lpFhR+VdVBuIsUcQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.17.tgz", + "integrity": "sha512-Bzv4p3ODgS/qpBE0DiJ9qf5WxSmrQ8gVTe8ClMfwwsY2x/rhykxxy3bXzG7AGTnPB2ij37zGJ/Q/6FruxHxsxg==", "dev": true, "requires": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.12.17" } }, "@babel/helper-optimise-call-expression": { @@ -2461,9 +2469,9 @@ } }, "@babel/parser": { - "version": "7.12.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.15.tgz", - "integrity": "sha512-AQBOU2Z9kWwSZMd6lNjCX0GUgFonL1wAM1db8L8PMk9UDaGsRCArBkU4Sc+UCM3AE4hjbXx+h58Lb3QT4oRmrA==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.17.tgz", + "integrity": "sha512-r1yKkiUTYMQ8LiEI0UcQx5ETw5dpTLn9wijn9hk6KkTtOK95FndDN10M+8/s6k/Ymlbivw0Av9q4SlgF80PtHg==", "dev": true }, "@babel/template": { @@ -2478,26 +2486,26 @@ } }, "@babel/traverse": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.13.tgz", - "integrity": "sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.17.tgz", + "integrity": "sha512-LGkTqDqdiwC6Q7fWSwQoas/oyiEYw6Hqjve5KOSykXkmFJFqzvGMb9niaUEag3Rlve492Mkye3gLw9FTv94fdQ==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.12.13", + "@babel/generator": "^7.12.17", "@babel/helper-function-name": "^7.12.13", "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13", + "@babel/parser": "^7.12.17", + "@babel/types": "^7.12.17", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", - "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.17.tgz", + "integrity": "sha512-tNMDjcv/4DIcHxErTgwB9q2ZcYyN0sUfgGKUK/mm1FJK7Wz+KstoEekxrl/tBiNDgLK1HGi+sppj1An/1DR4fQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", @@ -2568,9 +2576,9 @@ } }, "@babel/plugin-transform-runtime": { - "version": "7.12.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.15.tgz", - "integrity": "sha512-OwptMSRnRWJo+tJ9v9wgAf72ydXWfYSXWhnQjZing8nGZSDFqU1MBleKM3+DriKkcbv7RagA8gVeB0A1PNlNow==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.17.tgz", + "integrity": "sha512-s+kIJxnaTj+E9Q3XxQZ5jOo+xcogSe3V78/iFQ5RmoT0jROdpcdxhfGdq/VLqW1hFSzw6VjqN8aQqTaAMixWsw==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.12.13", @@ -2600,9 +2608,9 @@ "dev": true }, "@babel/types": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", - "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.17.tgz", + "integrity": "sha512-tNMDjcv/4DIcHxErTgwB9q2ZcYyN0sUfgGKUK/mm1FJK7Wz+KstoEekxrl/tBiNDgLK1HGi+sppj1An/1DR4fQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", @@ -2734,19 +2742,19 @@ } }, "@babel/preset-env": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.13.tgz", - "integrity": "sha512-JUVlizG8SoFTz4LmVUL8++aVwzwxcvey3N0j1tRbMAXVEy95uQ/cnEkmEKHN00Bwq4voAV3imQGnQvpkLAxsrw==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.17.tgz", + "integrity": "sha512-9PMijx8zFbCwTHrd2P4PJR5nWGH3zWebx2OcpTjqQrHhCiL2ssSR2Sc9ko2BsI2VmVBfoaQmPrlMTCui4LmXQg==", "dev": true, "requires": { "@babel/compat-data": "^7.12.13", - "@babel/helper-compilation-targets": "^7.12.13", + "@babel/helper-compilation-targets": "^7.12.17", "@babel/helper-module-imports": "^7.12.13", "@babel/helper-plugin-utils": "^7.12.13", - "@babel/helper-validator-option": "^7.12.11", + "@babel/helper-validator-option": "^7.12.17", "@babel/plugin-proposal-async-generator-functions": "^7.12.13", "@babel/plugin-proposal-class-properties": "^7.12.13", - "@babel/plugin-proposal-dynamic-import": "^7.12.1", + "@babel/plugin-proposal-dynamic-import": "^7.12.17", "@babel/plugin-proposal-export-namespace-from": "^7.12.13", "@babel/plugin-proposal-json-strings": "^7.12.13", "@babel/plugin-proposal-logical-assignment-operators": "^7.12.13", @@ -2754,7 +2762,7 @@ "@babel/plugin-proposal-numeric-separator": "^7.12.13", "@babel/plugin-proposal-object-rest-spread": "^7.12.13", "@babel/plugin-proposal-optional-catch-binding": "^7.12.13", - "@babel/plugin-proposal-optional-chaining": "^7.12.13", + "@babel/plugin-proposal-optional-chaining": "^7.12.17", "@babel/plugin-proposal-private-methods": "^7.12.13", "@babel/plugin-proposal-unicode-property-regex": "^7.12.13", "@babel/plugin-syntax-async-generators": "^7.8.0", @@ -2802,7 +2810,7 @@ "@babel/plugin-transform-unicode-escapes": "^7.12.13", "@babel/plugin-transform-unicode-regex": "^7.12.13", "@babel/preset-modules": "^0.1.3", - "@babel/types": "^7.12.13", + "@babel/types": "^7.12.17", "core-js-compat": "^3.8.0", "semver": "^5.5.0" }, @@ -2847,9 +2855,9 @@ } }, "@babel/types": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", - "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.17.tgz", + "integrity": "sha512-tNMDjcv/4DIcHxErTgwB9q2ZcYyN0sUfgGKUK/mm1FJK7Wz+KstoEekxrl/tBiNDgLK1HGi+sppj1An/1DR4fQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", @@ -2873,9 +2881,9 @@ } }, "@babel/runtime": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.13.tgz", - "integrity": "sha512-8+3UMPBrjFa/6TtKi/7sehPKqfAm4g6K+YQjyyFOLUTxzOngcRZTlAVY8sc2CORJYqdHQY8gRPHmn+qo15rCBw==", + "version": "7.12.18", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.18.tgz", + "integrity": "sha512-BogPQ7ciE6SYAUPtlm9tWbgI9+2AgqSam6QivMgXgAT+fKbgppaj4ZX15MHeLC1PVF5sNk70huBu20XxWOs8Cg==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" @@ -4093,9 +4101,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001185", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001185.tgz", - "integrity": "sha512-Fpi4kVNtNvJ15H0F6vwmXtb3tukv3Zg3qhKkOGUq7KJ1J6b9kf4dnNgtEAFXhRsJo0gNj9W60+wBvn0JcTvdTg==", + "version": "1.0.30001187", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001187.tgz", + "integrity": "sha512-w7/EP1JRZ9552CyrThUnay2RkZ1DXxKe/Q2swTC4+LElLh9RRYrL1Z+27LlakB8kzY0fSmHw9mc7XYDUKAKWMA==", "dev": true }, "capture-exit": { @@ -4302,12 +4310,12 @@ "dev": true }, "core-js-compat": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.8.3.tgz", - "integrity": "sha512-1sCb0wBXnBIL16pfFG1Gkvei6UzvKyTNYpiC41yrdjEv0UoJoq9E/abTMzyYJ6JpTkAj15dLjbqifIzEBDVvog==", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.9.0.tgz", + "integrity": "sha512-YK6fwFjCOKWwGnjFUR3c544YsnA/7DoLL0ysncuOJ4pwbriAtOpvM2bygdlcXbvQCQZ7bBU9CL4t7tGl7ETRpQ==", "dev": true, "requires": { - "browserslist": "^4.16.1", + "browserslist": "^4.16.3", "semver": "7.0.0" }, "dependencies": { @@ -4489,9 +4497,9 @@ "dev": true }, "detox": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/detox/-/detox-18.3.1.tgz", - "integrity": "sha512-eYvBTkJ0bvBcaWxubQBhRk+sT0Yd21npebd/s25BFrfB+8Ts4ctGASXh2uqlHkvCzUIDzRTEgFLu9I5k3g89Fw==", + "version": "18.6.2", + "resolved": "https://registry.npmjs.org/detox/-/detox-18.6.2.tgz", + "integrity": "sha512-p+qh6XBKapp1aPAUA/oa1wqjIi+bBthCE/WylfCnHOhmB3ZjaeloskS+8qpxCLtu6efcO6CoxLiD2aStjhn9/w==", "dev": true, "requires": { "bunyan": "^1.8.12", @@ -4563,9 +4571,9 @@ } }, "electron-to-chromium": { - "version": "1.3.661", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.661.tgz", - "integrity": "sha512-INNzKoL9ceOpPCpF5J+Fp9AOHY1RegwKViohAyTzV3XbkuRUx04r4v8edsDbevsog8UuL0GvD/Qerr2HwVTlSA==", + "version": "1.3.668", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.668.tgz", + "integrity": "sha512-TJzc4pxcplsWWS2hP01qQtwMIS+/3VLm4tkhsXbFwx3IIroXyidalrwcaJH+cNcrAdzSJ5xv0oeyGMS7d0i3kg==", "dev": true }, "emittery": { @@ -4969,9 +4977,9 @@ "dev": true }, "form-data": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz", - "integrity": "sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dev": true, "requires": { "asynckit": "^0.4.0", @@ -9559,9 +9567,9 @@ } }, "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "version": "20.2.5", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.5.tgz", + "integrity": "sha512-jYRGS3zWy20NtDtK2kBgo/TlAoy5YUuhD9/LZ7z7W4j1Fdw2cqD0xEEclf8fxc8xjD6X5Qr+qQQwCEsP8iRiYg==", "dev": true }, "yargs-unparser": { diff --git a/detox/package.json b/detox/package.json index 3cf9aff54..19a9c6e4e 100644 --- a/detox/package.json +++ b/detox/package.json @@ -6,14 +6,14 @@ "devDependencies": { "@babel/plugin-proposal-class-properties": "7.12.13", "@babel/plugin-transform-modules-commonjs": "7.12.13", - "@babel/plugin-transform-runtime": "7.12.15", - "@babel/preset-env": "7.12.13", + "@babel/plugin-transform-runtime": "7.12.17", + "@babel/preset-env": "7.12.17", "axios": "0.21.1", "babel-jest": "26.6.3", "babel-plugin-module-resolver": "4.1.0", "deepmerge": "4.2.2", - "detox": "18.3.1", - "form-data": "3.0.0", + "detox": "18.6.2", + "form-data": "4.0.0", "jest": "26.6.3", "jest-circus": "26.6.3", "jest-cli": "26.6.3", diff --git a/package-lock.json b/package-lock.json index e62ac3462..76e6ac836 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13311,9 +13311,9 @@ } }, "detox": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/detox/-/detox-18.3.1.tgz", - "integrity": "sha512-eYvBTkJ0bvBcaWxubQBhRk+sT0Yd21npebd/s25BFrfB+8Ts4ctGASXh2uqlHkvCzUIDzRTEgFLu9I5k3g89Fw==", + "version": "18.6.2", + "resolved": "https://registry.npmjs.org/detox/-/detox-18.6.2.tgz", + "integrity": "sha512-p+qh6XBKapp1aPAUA/oa1wqjIi+bBthCE/WylfCnHOhmB3ZjaeloskS+8qpxCLtu6efcO6CoxLiD2aStjhn9/w==", "dev": true, "requires": { "bunyan": "^1.8.12", @@ -13544,9 +13544,9 @@ } }, "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "version": "20.2.5", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.5.tgz", + "integrity": "sha512-jYRGS3zWy20NtDtK2kBgo/TlAoy5YUuhD9/LZ7z7W4j1Fdw2cqD0xEEclf8fxc8xjD6X5Qr+qQQwCEsP8iRiYg==", "dev": true } } diff --git a/package.json b/package.json index 2e0a150e9..13fe3fc07 100644 --- a/package.json +++ b/package.json @@ -123,7 +123,7 @@ "babel-plugin-module-resolver": "4.1.0", "babel-plugin-transform-remove-console": "6.9.4", "deep-freeze": "0.0.1", - "detox": "18.3.1", + "detox": "18.6.2", "enzyme": "3.11.0", "enzyme-adapter-react-16": "1.15.5", "enzyme-to-json": "3.6.1",