From 017c51c246179321f0857e6ebe566d6d66ef6c94 Mon Sep 17 00:00:00 2001 From: byigorv <60062354+byigorv@users.noreply.github.com> Date: Fri, 24 Mar 2023 08:52:37 +0300 Subject: [PATCH 01/46] fix mem leak in hubConnectionIndex (#22560) --- server/channels/app/platform/web_hub.go | 2 ++ server/channels/app/platform/web_hub_test.go | 37 ++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/server/channels/app/platform/web_hub.go b/server/channels/app/platform/web_hub.go index d37f3d4762..02652adf58 100644 --- a/server/channels/app/platform/web_hub.go +++ b/server/channels/app/platform/web_hub.go @@ -599,6 +599,8 @@ func (i *hubConnectionIndex) Remove(wc *WebConn) { last := userConnections[len(userConnections)-1] // set the slot that we are trying to remove to be the last connection. userConnections[userConnIndex] = last + // remove the last connection pointer from slice. + userConnections[len(userConnections)-1] = nil // remove the last connection from the slice. i.byUserId[wc.UserId] = userConnections[:len(userConnections)-1] // set the index of the connection that was moved to the new index. diff --git a/server/channels/app/platform/web_hub_test.go b/server/channels/app/platform/web_hub_test.go index 10db2fcb7c..0fc45e730c 100644 --- a/server/channels/app/platform/web_hub_test.go +++ b/server/channels/app/platform/web_hub_test.go @@ -8,6 +8,7 @@ import ( "net" "net/http" "net/http/httptest" + "runtime" "testing" "time" @@ -539,6 +540,42 @@ func BenchmarkHubConnIndex(b *testing.B) { }) } +func TestHubConnIndexRemoveMemLeak(t *testing.T) { + th := Setup(t) + defer th.TearDown() + + connIndex := newHubConnectionIndex(1 * time.Second) + + wc := &WebConn{ + Platform: th.Service, + Suite: th.Suite, + } + wc.SetConnectionID(model.NewId()) + wc.SetSession(&model.Session{}) + + ch := make(chan struct{}) + + runtime.SetFinalizer(wc, func(*WebConn) { + close(ch) + }) + + connIndex.Add(wc) + connIndex.Remove(wc) + + runtime.GC() + + timer := time.NewTimer(3 * time.Second) + defer timer.Stop() + + select { + case <-ch: + case <-timer.C: + require.Fail(t, "timeout waiting for collection of wc") + } + + assert.Len(t, connIndex.byConnection, 0) +} + var hubSink *Hub func BenchmarkGetHubForUserId(b *testing.B) { From 176a58617d977256d2e4c1ced0664c8f9d0f51a2 Mon Sep 17 00:00:00 2001 From: Agniva De Sarker Date: Fri, 24 Mar 2023 13:56:19 +0530 Subject: [PATCH 02/46] MM-51504: Control compliance export goroutine (#22604) Spawn a goroutine from the server layer to have better control for compliance tests. https://mattermost.atlassian.net/browse/MM-51504 ```release-note NONE ``` Co-authored-by: Mattermost Build --- server/channels/app/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/channels/app/server.go b/server/channels/app/server.go index c306f37e6a..c416089792 100644 --- a/server/channels/app/server.go +++ b/server/channels/app/server.go @@ -538,7 +538,7 @@ func (s *Server) runJobs() { }) if complianceI := s.Channels().Compliance; complianceI != nil { - complianceI.StartComplianceDailyJob() + go complianceI.StartComplianceDailyJob() } if *s.platform.Config().JobSettings.RunJobs && s.Jobs != nil { From 5c857e9df3f0ba25e28b1b418fa6bd8ef5f3873e Mon Sep 17 00:00:00 2001 From: Ibrahim Serdar Acikgoz Date: Fri, 24 Mar 2023 17:04:15 +0300 Subject: [PATCH 03/46] add concurrency limitation to gh actions (#22638) --- .github/workflows/channels-ci.yml | 3 +++ .github/workflows/ci.yml | 3 +++ .github/workflows/codeql-analysis.yml | 4 ++++ .github/workflows/e2e-ci.yml | 3 +++ 4 files changed, 13 insertions(+) diff --git a/.github/workflows/channels-ci.yml b/.github/workflows/channels-ci.yml index cc18459178..781cc6dd57 100644 --- a/.github/workflows/channels-ci.yml +++ b/.github/workflows/channels-ci.yml @@ -5,6 +5,9 @@ on: branches: - master - mono-repo* +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true defaults: run: shell: bash diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a2989782f0..dc5978a275 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,6 +7,9 @@ on: - cloud - release-* - mono-repo* +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true jobs: check-mocks: name: Check mocks diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 3c4f7e7f47..67779d669b 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,5 +1,9 @@ name: "CodeQL" +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + on: pull_request: # The branches below must be a subset of the branches above diff --git a/.github/workflows/e2e-ci.yml b/.github/workflows/e2e-ci.yml index 746c3389d4..923bb6cea4 100644 --- a/.github/workflows/e2e-ci.yml +++ b/.github/workflows/e2e-ci.yml @@ -5,6 +5,9 @@ on: branches: - master - mono-repo* +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true defaults: run: shell: bash From 379dbb1ca8ac232d1d561721d5ade474064aa791 Mon Sep 17 00:00:00 2001 From: Ibrahim Serdar Acikgoz Date: Fri, 24 Mar 2023 18:07:23 +0300 Subject: [PATCH 04/46] Add setup-go action (#22618) --- .github/workflows/ci.yml | 38 ++++++++++++++++++++++++++++++++++++++ .github/workflows/test.yml | 6 ++++++ 2 files changed, 44 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dc5978a275..70fe38e71b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,6 +7,8 @@ on: - cloud - release-* - mono-repo* +env: + go-version: "1.19.5" concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true @@ -20,6 +22,10 @@ jobs: steps: - name: Checkout mattermost-server uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + - name: Setup Go + uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 + with: + go-version: ${{ env.go-version }} - name: Generate mocks run: make mocks - name: Check mocks @@ -33,6 +39,10 @@ jobs: steps: - name: Checkout mattermost-server uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + - name: Setup Go + uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 + with: + go-version: ${{ env.go-version }} - name: Run go mod tidy run: make modules-tidy - name: Check modules @@ -46,6 +56,10 @@ jobs: steps: - name: Checkout mattermost-server uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + - name: Setup Go + uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 + with: + go-version: ${{ env.go-version }} - name: Run make-gen-serialized run: make gen-serialized - name: Check serialized @@ -59,6 +73,10 @@ jobs: steps: - name: Checkout mattermost-server uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + - name: Setup Go + uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 + with: + go-version: ${{ env.go-version }} - name: Reset config run: make config-reset - name: Run plugin-checker @@ -84,6 +102,10 @@ jobs: steps: - name: Checkout mattermost-server uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + - name: Setup Go + uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 + with: + go-version: ${{ env.go-version }} - name: Checkout mattermost-api-reference run: | cd .. @@ -102,6 +124,10 @@ jobs: steps: - name: Checkout mattermost-server uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + - name: Setup Go + uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 + with: + go-version: ${{ env.go-version }} - name: Generate work templates run: make generate-worktemplates - name: Check generated work templates @@ -130,6 +156,10 @@ jobs: steps: - name: Checkout mattermost-server uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + - name: Setup Go + uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 + with: + go-version: ${{ env.go-version }} - name: Generate store layers run: make store-layers - name: Check generated code @@ -143,6 +173,10 @@ jobs: steps: - name: Checkout mattermost-server uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + - name: Setup Go + uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 + with: + go-version: ${{ env.go-version }} - name: Generate app layers run: make app-layers - name: Check generated code @@ -178,6 +212,10 @@ jobs: steps: - name: Checkout mattermost-server uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + - name: Setup Go + uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 + with: + go-version: ${{ env.go-version }} - name: Build run: | make config-reset diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 291c4abef7..88e55d0168 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,6 +8,8 @@ on: drivername: required: true type: string +env: + go-version: "1.19.5" jobs: run-tests: runs-on: ubuntu-latest-8-cores @@ -17,6 +19,10 @@ jobs: steps: - name: Checkout mattermost-server uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + - name: Setup Go + uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 + with: + go-version: ${{ env.go-version }} - name: Run docker compose run: | cd server/build From 9105077ee11013e2f26652828f593a4836ac53e6 Mon Sep 17 00:00:00 2001 From: Nathaniel Allred Date: Fri, 24 Mar 2023 14:46:22 -0500 Subject: [PATCH 05/46] Mm 50735 (#22626) * add shipping address to self hosted signup model * purchase modals allow scroll * fix z-index issues with payment modal dropdowns --- model/hosted_customer.go | 9 +- .../choose_different_shipping.scss | 37 +++ .../choose_different_shipping/index.tsx | 45 ++++ .../src/components/dropdown_input.scss | 36 ++- .../components/payment_form/address_form.tsx | 42 ++-- .../components/payment_form/payment_form.scss | 2 - .../components/payment_form/payment_form.tsx | 2 +- .../components/purchase_modal/purchase.scss | 38 +-- .../purchase_modal/purchase_modal.tsx | 3 +- .../self_hosted_purchase_modal/address.tsx | 132 ++++++++++ .../self_hosted_purchase_modal/index.test.tsx | 24 ++ .../self_hosted_purchase_modal/index.tsx | 227 ++++++++++-------- .../self_hosted_purchase_modal.scss | 10 +- webapp/channels/src/i18n/en.json | 1 + webapp/platform/types/src/hosted_customer.ts | 1 + 15 files changed, 438 insertions(+), 171 deletions(-) create mode 100644 webapp/channels/src/components/choose_different_shipping/choose_different_shipping.scss create mode 100644 webapp/channels/src/components/choose_different_shipping/index.tsx create mode 100644 webapp/channels/src/components/self_hosted_purchase_modal/address.tsx diff --git a/model/hosted_customer.go b/model/hosted_customer.go index 4f1917bdaf..543ea12b74 100644 --- a/model/hosted_customer.go +++ b/model/hosted_customer.go @@ -21,10 +21,11 @@ type BootstrapSelfHostedSignupResponseInternal struct { // email contained in token, so not in the request body. type SelfHostedCustomerForm struct { - FirstName string `json:"first_name"` - LastName string `json:"last_name"` - BillingAddress *Address `json:"billing_address"` - Organization string `json:"organization"` + FirstName string `json:"first_name"` + LastName string `json:"last_name"` + BillingAddress *Address `json:"billing_address"` + ShippingAddress *Address `json:"shipping_address"` + Organization string `json:"organization"` } type SelfHostedConfirmPaymentMethodRequest struct { diff --git a/webapp/channels/src/components/choose_different_shipping/choose_different_shipping.scss b/webapp/channels/src/components/choose_different_shipping/choose_different_shipping.scss new file mode 100644 index 0000000000..322997fc03 --- /dev/null +++ b/webapp/channels/src/components/choose_different_shipping/choose_different_shipping.scss @@ -0,0 +1,37 @@ +.shipping-address-section { + display: flex; + align-content: flex-start; + padding-bottom: 24px; + font-weight: normal; + + button.no-style { + padding-left: 0; + border: none; + background: transparent; + outline: unset; + text-align: left; + + &:focus { + outline: unset; + } + } + + #address-same-than-billing-address { + width: 17px; + height: 17px; + flex-shrink: 0; + } + + .Form-checkbox-label { + padding-left: 12px; + cursor: default; + font-family: 'Open Sans', sans-serif; + vertical-align: middle; + } + + .billing_address_btn_text { + color: var(--center-channel-color); + font-family: 'Open Sans', sans-serif; + font-weight: bold; + } +} diff --git a/webapp/channels/src/components/choose_different_shipping/index.tsx b/webapp/channels/src/components/choose_different_shipping/index.tsx new file mode 100644 index 0000000000..43b810f2e8 --- /dev/null +++ b/webapp/channels/src/components/choose_different_shipping/index.tsx @@ -0,0 +1,45 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react'; + +import {useIntl} from 'react-intl'; + +import './choose_different_shipping.scss'; + +interface Props { + shippingIsSame: boolean; + setShippingIsSame: (different: boolean) => void; +} +export default function ChooseDifferentShipping(props: Props) { + const intl = useIntl(); + const toggle = () => props.setShippingIsSame(!props.shippingIsSame); + + return ( +
+ + + + +
+ ); +} diff --git a/webapp/channels/src/components/dropdown_input.scss b/webapp/channels/src/components/dropdown_input.scss index e654e78d5c..1420223f21 100644 --- a/webapp/channels/src/components/dropdown_input.scss +++ b/webapp/channels/src/components/dropdown_input.scss @@ -1,5 +1,7 @@ +$dropdown_input_index: 999999; + .DropdownInput { - z-index: 999999; + z-index: $dropdown_input_index; &.Input_container { margin-top: 20px; @@ -37,7 +39,7 @@ } .DropdownInput__option > div { - z-index: 999999; + z-index: $dropdown_input_index; padding: 10px 24px; cursor: pointer; line-height: 16px; @@ -51,3 +53,33 @@ .DropdownInput__option.focused > div { background-color: rgba(var(--center-channel-color-rgb), 0.08); } + +.second-dropdown-sibling-wrapper { + .DropdownInput { + z-index: $dropdown_input_index - 1; + } + + .DropdownInput__option > div { + z-index: $dropdown_input_index - 1; + } +} + +.third-dropdown-sibling-wrapper { + .DropdownInput { + z-index: $dropdown_input_index - 2; + } + + .DropdownInput__option > div { + z-index: $dropdown_input_index - 2; + } +} + +.fourth-dropdown-sibling-wrapper { + .DropdownInput { + z-index: $dropdown_input_index - 3; + } + + .DropdownInput__option > div { + z-index: $dropdown_input_index - 3; + } +} diff --git a/webapp/channels/src/components/payment_form/address_form.tsx b/webapp/channels/src/components/payment_form/address_form.tsx index 651861b8d1..470f45da88 100644 --- a/webapp/channels/src/components/payment_form/address_form.tsx +++ b/webapp/channels/src/components/payment_form/address_form.tsx @@ -61,25 +61,27 @@ const AddressForm = (props: AddressFormProps) => { {...props.title} /> - ({ - value: country.name, - label: country.name, - }))} - legend={formatMessage({ - id: 'payment_form.country', - defaultMessage: 'Country', - })} - placeholder={formatMessage({ - id: 'payment_form.country', - defaultMessage: 'Country', - })} - name={'billing_dropdown'} - /> +
+ ({ + value: country.name, + label: country.name, + }))} + legend={formatMessage({ + id: 'payment_form.country', + defaultMessage: 'Country', + })} + placeholder={formatMessage({ + id: 'payment_form.country', + defaultMessage: 'Country', + })} + name={'billing_dropdown'} + /> +
{ />
-
+
{ />
-
+
div { diff --git a/webapp/channels/src/components/purchase_modal/purchase_modal.tsx b/webapp/channels/src/components/purchase_modal/purchase_modal.tsx index bf4abc4804..36b39a3ab0 100644 --- a/webapp/channels/src/components/purchase_modal/purchase_modal.tsx +++ b/webapp/channels/src/components/purchase_modal/purchase_modal.tsx @@ -6,6 +6,7 @@ import React, {ReactNode} from 'react'; import {FormattedMessage, injectIntl, IntlShape} from 'react-intl'; +import classnames from 'classnames'; import {Stripe, StripeCardElementChangeEvent} from '@stripe/stripe-js'; import {loadStripe} from '@stripe/stripe-js/pure'; // https://github.com/stripe/stripe-js#importing-loadstripe-without-side-effects import {Elements} from '@stripe/react-stripe-js'; @@ -812,7 +813,7 @@ class PurchaseModal extends React.PureComponent { } return ( -
+

{title}

void; + + address: string; + changeAddress: (e: React.ChangeEvent) => void; + + address2: string; + changeAddress2: (e: React.ChangeEvent) => void; + + city: string; + changeCity: (e: React.ChangeEvent) => void; + + state: string; + changeState: (postalCode: string) => void; + + postalCode: string; + changePostalCode: (e: React.ChangeEvent) => void; +} +export default function Address(props: Props) { + const testPrefix = props.testPrefix || 'selfHostedPurchase'; + const intl = useIntl(); + let countrySelectorId = `${testPrefix}CountrySelector`; + let stateSelectorId = `${testPrefix}StateSelector`; + if (props.type === 'shipping') { + countrySelectorId += '_Shipping'; + stateSelectorId += '_Shipping'; + } + return ( + <> +
+ ({ + value: country.name, + label: country.name, + }))} + legend={intl.formatMessage({ + id: 'payment_form.country', + defaultMessage: 'Country', + })} + placeholder={intl.formatMessage({ + id: 'payment_form.country', + defaultMessage: 'Country', + })} + name={'billing_dropdown'} + /> +
+
+ +
+
+ +
+
+ +
+
+
+ +
+
+ +
+
+ + ); +} diff --git a/webapp/channels/src/components/self_hosted_purchase_modal/index.test.tsx b/webapp/channels/src/components/self_hosted_purchase_modal/index.test.tsx index 5a3fbf6bda..3ccbb74ce2 100644 --- a/webapp/channels/src/components/self_hosted_purchase_modal/index.test.tsx +++ b/webapp/channels/src/components/self_hosted_purchase_modal/index.test.tsx @@ -310,6 +310,15 @@ describe('SelfHostedPurchaseModal :: canSubmit', () => { state: 'string', country: 'string', postalCode: '12345', + + shippingSame: true, + shippingAddress: '', + shippingAddress2: '', + shippingCity: '', + shippingState: '', + shippingCountry: '', + shippingPostalCode: '', + cardName: 'string', organization: 'string', agreedTerms: true, @@ -361,6 +370,21 @@ describe('SelfHostedPurchaseModal :: canSubmit', () => { expect(canSubmit(state, SelfHostedSignupProgress.CREATED_CUSTOMER)).toBe(false); expect(canSubmit(state, SelfHostedSignupProgress.CREATED_INTENT)).toBe(false); }); + + it('if shipping address different and is not filled, can not submit', () => { + const state = makeHappyPathState(); + state.shippingSame = false; + expect(canSubmit(state, SelfHostedSignupProgress.START)).toBe(false); + + state.shippingAddress = 'more shipping info'; + state.shippingAddress2 = 'more shipping info'; + state.shippingCity = 'more shipping info'; + state.shippingState = 'more shipping info'; + state.shippingCountry = 'more shipping info'; + state.shippingPostalCode = 'more shipping info'; + expect(canSubmit(state, SelfHostedSignupProgress.START)).toBe(true); + }); + it('if card number missing and card has not been confirmed, can not submit', () => { const state = makeHappyPathState(); state.cardFilled = false; diff --git a/webapp/channels/src/components/self_hosted_purchase_modal/index.tsx b/webapp/channels/src/components/self_hosted_purchase_modal/index.tsx index 03bfbccddc..af43bfd229 100644 --- a/webapp/channels/src/components/self_hosted_purchase_modal/index.tsx +++ b/webapp/channels/src/components/self_hosted_purchase_modal/index.tsx @@ -26,8 +26,6 @@ import {GlobalState} from 'types/store'; import {isModalOpen} from 'selectors/views/modals'; import {isDevModeEnabled} from 'selectors/general'; -import {COUNTRIES} from 'utils/countries'; - import { ModalIdentifiers, StatTypes, @@ -35,8 +33,6 @@ import { } from 'utils/constants'; import CardInput, {CardInputType} from 'components/payment_form/card_input'; -import StateSelector from 'components/payment_form/state_selector'; -import DropdownInput from 'components/dropdown_input'; import BackgroundSvg from 'components/common/svg_images_components/background_svg'; import UpgradeSvg from 'components/common/svg_images_components/upgrade_svg'; @@ -47,6 +43,7 @@ import RootPortal from 'components/root_portal'; import useLoadStripe from 'components/common/hooks/useLoadStripe'; import useControlSelfHostedPurchaseModal from 'components/common/hooks/useControlSelfHostedPurchaseModal'; import useFetchStandardAnalytics from 'components/common/hooks/useFetchStandardAnalytics'; +import ChooseDifferentShipping from 'components/choose_different_shipping'; import {ValueOf} from '@mattermost/types/utilities'; import {UserProfile} from '@mattermost/types/users'; @@ -64,6 +61,7 @@ import SuccessPage from './success_page'; import SelfHostedCard from './self_hosted_card'; import StripeProvider from './stripe_provider'; import Terms from './terms'; +import Address from './address'; import useNoEscape from './useNoEscape'; import {SetPrefix, UnionSetActions} from './types'; @@ -73,12 +71,24 @@ import './self_hosted_purchase_modal.scss'; import {STORAGE_KEY_PURCHASE_IN_PROGRESS} from './constants'; export interface State { + + // billing address address: string; address2: string; city: string; state: string; country: string; postalCode: string; + + // shipping address + shippingSame: boolean; + shippingAddress: string; + shippingAddress2: string; + shippingCity: string; + shippingState: string; + shippingCountry: string; + shippingPostalCode: string; + cardName: string; organization: string; agreedTerms: boolean; @@ -113,6 +123,15 @@ export function makeInitialState(): State { state: '', country: '', postalCode: '', + + shippingSame: true, + shippingAddress: '', + shippingAddress2: '', + shippingCity: '', + shippingState: '', + shippingCountry: '', + shippingPostalCode: '', + cardName: '', organization: '', agreedTerms: false, @@ -170,8 +189,18 @@ const simpleSetters: Array> = [ 'address2', 'city', 'country', - 'postalCode', 'state', + 'postalCode', + + // shipping address + 'shippingSame', + 'shippingAddress', + 'shippingAddress2', + 'shippingCity', + 'shippingState', + 'shippingCountry', + 'shippingPostalCode', + 'agreedTerms', 'cardFilled', 'cardName', @@ -220,7 +249,7 @@ export function canSubmit(state: State, progress: ValueOf
- { +
{ dispatch({type: 'set_country', data: option.value}); }} - value={ - state.country ? {value: state.country, label: state.country} : undefined - } - options={COUNTRIES.map((country) => ({ - value: country.name, - label: country.name, - }))} - legend={intl.formatMessage({ - id: 'payment_form.country', - defaultMessage: 'Country', - })} - placeholder={intl.formatMessage({ - id: 'payment_form.country', - defaultMessage: 'Country', - })} - name={'billing_dropdown'} + address={state.address} + changeAddress={(e) => { + dispatch({type: 'set_address', data: e.target.value}); + }} + address2={state.address2} + changeAddress2={(e) => { + dispatch({type: 'set_address2', data: e.target.value}); + }} + city={state.city} + changeCity={(e) => { + dispatch({type: 'set_city', data: e.target.value}); + }} + state={state.state} + changeState={(state: string) => { + dispatch({type: 'set_state', data: state}); + }} + postalCode={state.postalCode} + changePostalCode={(e) => { + dispatch({type: 'set_postalCode', data: e.target.value}); + }} /> -
- ) => { - dispatch({type: 'set_address', data: e.target.value}); - }} - placeholder={intl.formatMessage({ - id: 'payment_form.address', - defaultMessage: 'Address', - })} - required={true} - /> -
-
- ) => { - dispatch({type: 'set_address2', data: e.target.value}); - }} - placeholder={intl.formatMessage({ - id: 'payment_form.address_2', - defaultMessage: 'Address 2', - })} - /> -
-
- ) => { - dispatch({type: 'set_city', data: e.target.value}); - }} - placeholder={intl.formatMessage({ - id: 'payment_form.city', - defaultMessage: 'City', - })} - required={true} - /> -
-
-
- { - dispatch({type: 'set_state', data: state}); + { + dispatch({type: 'set_shippingSame', data: val}); + }} + /> + {!state.shippingSame && ( + <> +
+ +
+
{ + dispatch({type: 'set_shippingCountry', data: option.value}); + }} + address={state.shippingAddress} + changeAddress={(e) => { + dispatch({type: 'set_shippingAddress', data: e.target.value}); + }} + address2={state.shippingAddress2} + changeAddress2={(e) => { + dispatch({type: 'set_shippingAddress2', data: e.target.value}); + }} + city={state.shippingCity} + changeCity={(e) => { + dispatch({type: 'set_shippingCity', data: e.target.value}); + }} + state={state.shippingState} + changeState={(state: string) => { + dispatch({type: 'set_shippingState', data: state}); + }} + postalCode={state.shippingPostalCode} + changePostalCode={(e) => { + dispatch({type: 'set_shippingPostalCode', data: e.target.value}); }} /> -
-
- ) => { - dispatch({type: 'set_postalCode', data: e.target.value}); - }} - placeholder={intl.formatMessage({ - id: 'payment_form.zipcode', - defaultMessage: 'Zip/Postal Code', - })} - required={true} - /> -
-
+ + )} { diff --git a/webapp/channels/src/components/self_hosted_purchase_modal/self_hosted_purchase_modal.scss b/webapp/channels/src/components/self_hosted_purchase_modal/self_hosted_purchase_modal.scss index e949e76e20..52bac49aec 100644 --- a/webapp/channels/src/components/self_hosted_purchase_modal/self_hosted_purchase_modal.scss +++ b/webapp/channels/src/components/self_hosted_purchase_modal/self_hosted_purchase_modal.scss @@ -4,19 +4,20 @@ .form-view { display: flex; - overflow: hidden; width: 100%; height: 100%; flex-direction: row; flex-grow: 1; flex-wrap: wrap; - align-content: top; + align-items: flex-start; justify-content: center; padding: 77px 107px; color: var(--center-channel-color); font-family: "Open Sans"; font-size: 16px; font-weight: 600; + overflow-x: hidden; + overflow-y: auto; .title { font-size: 22px; @@ -39,14 +40,12 @@ margin-right: 16px; .DropdownInput { - z-index: 99999; margin-top: 0; } } .DropdownInput { position: relative; - z-index: 999999; height: 36px; margin-bottom: 24px; @@ -517,6 +516,9 @@ } input[type=checkbox] { + width: 17px; + height: 17px; + flex-shrink: 0; margin-right: 12px; } diff --git a/webapp/channels/src/i18n/en.json b/webapp/channels/src/i18n/en.json index c4f6025f80..6c28bff86c 100644 --- a/webapp/channels/src/i18n/en.json +++ b/webapp/channels/src/i18n/en.json @@ -4378,6 +4378,7 @@ "payment_form.no_billing_address": "No billing address added", "payment_form.no_credit_card": "No credit card added", "payment_form.saved_payment_method": "Saved Payment Method", + "payment_form.shipping_address": "Shipping Address", "payment_form.zipcode": "Zip/Postal Code", "payment.card_number": "Card Number", "payment.field_required": "This field is required", diff --git a/webapp/platform/types/src/hosted_customer.ts b/webapp/platform/types/src/hosted_customer.ts index d81ef15227..fcd5b4e70b 100644 --- a/webapp/platform/types/src/hosted_customer.ts +++ b/webapp/platform/types/src/hosted_customer.ts @@ -18,6 +18,7 @@ export interface SelfHostedSignupForm { first_name: string; last_name: string; billing_address: Address; + shipping_address: Address; organization: string; } From 067784dc4a0665fe66bc52aeb8cf4f251040fa53 Mon Sep 17 00:00:00 2001 From: Nathaniel Allred Date: Fri, 24 Mar 2023 14:51:28 -0500 Subject: [PATCH 06/46] Fix EmailSettings.FeedbackEmail client validation (#22611) * fix EmailSettings.FeedbackEmail client validation --- .../src/components/admin_console/admin_definition.jsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/webapp/channels/src/components/admin_console/admin_definition.jsx b/webapp/channels/src/components/admin_console/admin_definition.jsx index 387b13825b..5eab5ed08f 100644 --- a/webapp/channels/src/components/admin_console/admin_definition.jsx +++ b/webapp/channels/src/components/admin_console/admin_definition.jsx @@ -2497,7 +2497,11 @@ const AdminDefinition = { it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.SITE.NOTIFICATIONS)), it.stateIsFalse('EmailSettings.SendEmailNotifications'), ), - validate: validators.isRequired(t('admin.environment.notifications.feedbackEmail.required'), '"Notification From Address" is required'), + + // MM-50952 + // If the setting is hidden, then it is not being set in state so there is + // nothing to validate, and validation would fail anyways and prevent saving + validate: it.configIsFalse('ExperimentalSettings', 'RestrictSystemAdmin') && validators.isRequired(t('admin.environment.notifications.feedbackEmail.required'), '"Notification From Address" is required'), }, { type: Constants.SettingsTypes.TYPE_TEXT, From d8d3c6e7a65ea7140647218280c72873f380a606 Mon Sep 17 00:00:00 2001 From: Agniva De Sarker Date: Mon, 27 Mar 2023 10:28:16 +0530 Subject: [PATCH 07/46] MM-51699: Skip flaky test (#22635) https://mattermost.atlassian.net/browse/MM-51699 ```release-note NONE ``` --- server/boards/app/boards_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/server/boards/app/boards_test.go b/server/boards/app/boards_test.go index 97dbe1ccd0..9ea4c4b59d 100644 --- a/server/boards/app/boards_test.go +++ b/server/boards/app/boards_test.go @@ -140,6 +140,7 @@ func TestAddMemberToBoard(t *testing.T) { } func TestPatchBoard(t *testing.T) { + t.Skip("MM-51699") th, tearDown := SetupTestHelper(t) defer tearDown() From 5072cd7bdf3b6834112a2ea1a783baafb930e158 Mon Sep 17 00:00:00 2001 From: Ibrahim Serdar Acikgoz Date: Mon, 27 Mar 2023 10:01:02 +0300 Subject: [PATCH 08/46] Trigger master branch for builds (#22616) --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4f7ec1b64a..e6b27c644d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,7 +7,7 @@ stages: include: - project: mattermost/ci/mattermost-server - ref: monorepo-testing + ref: master file: private.yml variables: From ee068726bcd3519bb45ed47c222cc4cd99e2ba5a Mon Sep 17 00:00:00 2001 From: Allan Guwatudde Date: Mon, 27 Mar 2023 10:50:45 +0300 Subject: [PATCH 09/46] [MM-51467] - NotifyAdmin job reports an error for unlicensed servers (#22568) * [MM-51467] - Reduce frequency for notify install plugin job * [MM-51467] - NotifyAdmin job reports an error for unlicensed servers * . * fix imports --- server/channels/app/notify_admin.go | 6 +++--- .../channels/jobs/notify_admin/install_plugin_scheduler.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/server/channels/app/notify_admin.go b/server/channels/app/notify_admin.go index 908134b4b2..87a294c55f 100644 --- a/server/channels/app/notify_admin.go +++ b/server/channels/app/notify_admin.go @@ -48,12 +48,12 @@ func (a *App) SaveAdminNotification(userId string, notifyData *model.NotifyAdmin func (a *App) DoCheckForAdminNotifications(trial bool) *model.AppError { ctx := request.EmptyContext(a.Srv().Log()) + currentSKU := "starter" license := a.Srv().License() - if license == nil { - return model.NewAppError("DoCheckForAdminNotifications", "app.notify_admin.send_notification_post.app_error", nil, "No license found", http.StatusInternalServerError) + if license != nil { + currentSKU = license.SkuShortName } - currentSKU := license.SkuShortName workspaceName := "" return a.SendNotifyAdminPosts(ctx, workspaceName, currentSKU, trial) diff --git a/server/channels/jobs/notify_admin/install_plugin_scheduler.go b/server/channels/jobs/notify_admin/install_plugin_scheduler.go index 36b9818635..91ebdb79c1 100644 --- a/server/channels/jobs/notify_admin/install_plugin_scheduler.go +++ b/server/channels/jobs/notify_admin/install_plugin_scheduler.go @@ -12,7 +12,7 @@ import ( "github.com/mattermost/mattermost-server/v6/server/platform/shared/mlog" ) -const installPluginSchedFreq = 1 * time.Minute +const installPluginSchedFreq = 24 * time.Hour func MakeInstallPluginScheduler(jobServer *jobs.JobServer, license *model.License, jobType string) model.Scheduler { isEnabled := func(cfg *model.Config) bool { From 3e85a9bb3ac71480ec3e8b0ffd2c322159a644e7 Mon Sep 17 00:00:00 2001 From: Harshil Sharma <18575143+harshilsharma63@users.noreply.github.com> Date: Mon, 27 Mar 2023 13:23:05 +0530 Subject: [PATCH 10/46] Updated query to support old mysql version (#22606) * Updated query to support old mysql version * Added tests * Using foundation for tests * Removed unused override params * Removed unused override params --- .../store/sqlstore/boards_migrator.go | 3 +++ .../store/sqlstore/data_migrations.go | 6 ++--- .../store/sqlstore/data_migrations_test.go | 23 +++++++++++++++++++ ...testDeDuplicateCategoryBoardsMigration.sql | 9 ++++++++ .../{helpers_test.go => helpers.go} | 4 ++++ .../boards/services/store/sqlstore/testlib.go | 1 + 6 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 server/boards/services/store/sqlstore/fixtures/testDeDuplicateCategoryBoardsMigration.sql rename server/boards/services/store/sqlstore/migrationstests/{helpers_test.go => helpers.go} (90%) diff --git a/server/boards/services/store/sqlstore/boards_migrator.go b/server/boards/services/store/sqlstore/boards_migrator.go index 99395e9e46..79afeddc66 100644 --- a/server/boards/services/store/sqlstore/boards_migrator.go +++ b/server/boards/services/store/sqlstore/boards_migrator.go @@ -231,6 +231,9 @@ func (bm *BoardsMigrator) MigrateToStep(step int) error { func (bm *BoardsMigrator) Interceptors() map[int]foundation.Interceptor { return map[int]foundation.Interceptor{ 18: bm.store.RunDeletedMembershipBoardsMigration, + 35: func() error { + return bm.store.RunDeDuplicateCategoryBoardsMigration(35) + }, } } diff --git a/server/boards/services/store/sqlstore/data_migrations.go b/server/boards/services/store/sqlstore/data_migrations.go index a1404afac8..8e18022319 100644 --- a/server/boards/services/store/sqlstore/data_migrations.go +++ b/server/boards/services/store/sqlstore/data_migrations.go @@ -863,10 +863,8 @@ func (s *SQLStore) doesDuplicateCategoryBoardsExist() (bool, error) { } func (s *SQLStore) runMySQLDeDuplicateCategoryBoardsMigration() error { - query := "WITH duplicates AS (SELECT id, ROW_NUMBER() OVER(PARTITION BY user_id, board_id) AS rownum " + - "FROM " + s.tablePrefix + "category_boards) " + - "DELETE " + s.tablePrefix + "category_boards FROM " + s.tablePrefix + "category_boards " + - "JOIN duplicates USING(id) WHERE duplicates.rownum > 1;" + query := "DELETE FROM " + s.tablePrefix + "category_boards WHERE id NOT IN " + + "(SELECT * FROM ( SELECT min(id) FROM " + s.tablePrefix + "category_boards GROUP BY user_id, board_id ) as data)" if _, err := s.db.Exec(query); err != nil { s.logger.Error("Failed to de-duplicate data in category_boards table", mlog.Err(err)) } diff --git a/server/boards/services/store/sqlstore/data_migrations_test.go b/server/boards/services/store/sqlstore/data_migrations_test.go index e5aae4de52..5a44f9ca2e 100644 --- a/server/boards/services/store/sqlstore/data_migrations_test.go +++ b/server/boards/services/store/sqlstore/data_migrations_test.go @@ -7,6 +7,9 @@ import ( "testing" "time" + "github.com/mattermost/mattermost-server/v6/server/boards/services/store/sqlstore/migrationstests" + "github.com/mgdelacroix/foundation" + "github.com/mattermost/mattermost-server/v6/server/boards/model" "github.com/stretchr/testify/assert" @@ -263,3 +266,23 @@ func TestCheckForMismatchedCollation(t *testing.T) { } }) } + +func TestRunDeDuplicateCategoryBoardsMigration(t *testing.T) { + RunStoreTestsWithFoundation(t, func(t *testing.T, f *foundation.Foundation) { + th, tearDown := migrationstests.SetupTestHelper(t, f) + defer tearDown() + + th.F().MigrateToStepSkippingLastInterceptor(35). + ExecFile("./fixtures/testDeDuplicateCategoryBoardsMigration.sql") + + th.F().RunInterceptor(35) + + // verifying count of rows + var count int + countQuery := "SELECT COUNT(*) FROM focalboard_category_boards" + row := th.F().DB().QueryRow(countQuery) + err := row.Scan(&count) + assert.NoError(t, err) + assert.Equal(t, 4, count) + }) +} diff --git a/server/boards/services/store/sqlstore/fixtures/testDeDuplicateCategoryBoardsMigration.sql b/server/boards/services/store/sqlstore/fixtures/testDeDuplicateCategoryBoardsMigration.sql new file mode 100644 index 0000000000..69a7dc9bde --- /dev/null +++ b/server/boards/services/store/sqlstore/fixtures/testDeDuplicateCategoryBoardsMigration.sql @@ -0,0 +1,9 @@ +INSERT INTO focalboard_category_boards(id, user_id, category_id, board_id, create_at, update_at, sort_order) +VALUES + ('id_1', 'user_id_1', 'category_id_1', 'board_id_1', 0, 0, 0), + ('id_2', 'user_id_1', 'category_id_2', 'board_id_1', 0, 0, 0), + ('id_3', 'user_id_1', 'category_id_3', 'board_id_1', 0, 0, 0), + ('id_4', 'user_id_2', 'category_id_4', 'board_id_2', 0, 0, 0), + ('id_5', 'user_id_2', 'category_id_5', 'board_id_2', 0, 0, 0), + ('id_6', 'user_id_3', 'category_id_6', 'board_id_3', 0, 0, 0), + ('id_7', 'user_id_4', 'category_id_6', 'board_id_4', 0, 0, 0); diff --git a/server/boards/services/store/sqlstore/migrationstests/helpers_test.go b/server/boards/services/store/sqlstore/migrationstests/helpers.go similarity index 90% rename from server/boards/services/store/sqlstore/migrationstests/helpers_test.go rename to server/boards/services/store/sqlstore/migrationstests/helpers.go index a6d4696f14..a674d5f988 100644 --- a/server/boards/services/store/sqlstore/migrationstests/helpers_test.go +++ b/server/boards/services/store/sqlstore/migrationstests/helpers.go @@ -22,6 +22,10 @@ func (th *TestHelper) IsMySQL() bool { return th.f.DB().DriverName() == "mysql" } +func (th *TestHelper) F() *foundation.Foundation { + return th.f +} + func SetupTestHelper(t *testing.T, f *foundation.Foundation) (*TestHelper, func()) { th := &TestHelper{t, f} diff --git a/server/boards/services/store/sqlstore/testlib.go b/server/boards/services/store/sqlstore/testlib.go index 9ea7de4301..a79b2a1643 100644 --- a/server/boards/services/store/sqlstore/testlib.go +++ b/server/boards/services/store/sqlstore/testlib.go @@ -50,6 +50,7 @@ func NewStoreType(name string, driver string, skipMigrations bool) *storeType { DB: sqlDB, IsPlugin: false, // ToDo: to be removed } + store, err := New(storeParams) if err != nil { panic(fmt.Sprintf("cannot create store: %s", err)) From 26c3b4668b117d2e98db10bd5b6603831a6a2e81 Mon Sep 17 00:00:00 2001 From: Kyriakos Z <3829551+koox00@users.noreply.github.com> Date: Mon, 27 Mar 2023 13:42:27 +0300 Subject: [PATCH 11/46] MM-51436: fixes broken link (#22655) --- .../src/components/post_priority/post_priority_picker.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/channels/src/components/post_priority/post_priority_picker.tsx b/webapp/channels/src/components/post_priority/post_priority_picker.tsx index 568c6a1fa9..6f8ca90d30 100644 --- a/webapp/channels/src/components/post_priority/post_priority_picker.tsx +++ b/webapp/channels/src/components/post_priority/post_priority_picker.tsx @@ -155,7 +155,7 @@ function PostPriorityPicker({ } } - const feedbackLink = postAcknowledgementsEnabled ? 'https://forms.gle/noA8Azg7RdaBZtMB6' : 'https://forms.gle/XRb63s3KZqpLNyqr9'; + const feedbackLink = postAcknowledgementsEnabled ? 'https://forms.gle/noA8Azg7RdaBZtMB6' : 'https://forms.gle/mMcRFQzyKAo9Sv49A'; return ( Date: Mon, 27 Mar 2023 08:21:29 -0500 Subject: [PATCH 12/46] return 404 if the enterprise library error returned is 404 (#22628) --- server/channels/api4/hosted_customer.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/server/channels/api4/hosted_customer.go b/server/channels/api4/hosted_customer.go index 4792969c15..cead966f41 100644 --- a/server/channels/api4/hosted_customer.go +++ b/server/channels/api4/hosted_customer.go @@ -13,6 +13,8 @@ import ( "reflect" "time" + "github.com/pkg/errors" + "github.com/mattermost/mattermost-server/v6/model" "github.com/mattermost/mattermost-server/v6/server/channels/utils" "github.com/mattermost/mattermost-server/v6/server/platform/shared/mlog" @@ -250,6 +252,10 @@ func selfHostedInvoices(c *Context, w http.ResponseWriter, r *http.Request) { invoices, err := c.App.Cloud().GetSelfHostedInvoices() if err != nil { + if err.Error() == "404" { + c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusNotFound).Wrap(errors.New("invoices for license not found")) + return + } c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err) return } From 5215a0c30d9f027a58a2d062601cc60eb302cff0 Mon Sep 17 00:00:00 2001 From: Jesse Hallam Date: Mon, 27 Mar 2023 10:54:06 -0300 Subject: [PATCH 13/46] update LICENSE.txt (#22659) --- LICENSE.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index 8ced25a132..eb417456e4 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -11,8 +11,8 @@ You may be licensed to use source code to create compiled versions not produced 1. Under the Free Software Foundation’s GNU AGPL v.3.0, subject to the exceptions outlined in this policy; or 2. Under a commercial license available from Mattermost, Inc. by contacting commercial@mattermost.com -You are licensed to use the source code in Admin Tools and Configuration Files (templates/, config/default.json, i18n/, model/, -plugin/ and all subdirectories thereof) under the Apache License v2.0. +You are licensed to use the source code in Admin Tools and Configuration Files (server/templates/, server/i18n/, model/, +plugin/, server/boards/, server/playbooks/, webapp/ and all subdirectories thereof) under the Apache License v2.0. We promise that we will not enforce the copyleft provisions in AGPL v3.0 against you if your application (a) does not link to the Mattermost Platform directly, but exclusively uses the Mattermost Admin Tools and Configuration Files, and From 865b3d75e7f69fa582a504f945226a41f442a950 Mon Sep 17 00:00:00 2001 From: Allan Guwatudde Date: Mon, 27 Mar 2023 17:42:07 +0300 Subject: [PATCH 14/46] [MM-50976] - Contact Support to redirect to Zendesk and pre-fill known information (#22640) --- .../cancel_subscription.tsx | 14 +-- .../cloud_trial_banner.tsx | 3 +- .../contact_sales_card.tsx | 10 +- .../billing/billing_subscriptions/index.tsx | 13 +-- .../limit_reached_banner.test.tsx | 2 +- .../limit_reached_banner.tsx | 4 +- .../billing/billing_subscriptions/limits.tsx | 4 +- .../to_yearly_nudge_banner.tsx | 3 +- .../billing/delete_workspace/result_modal.tsx | 13 +-- .../feature_discovery.test.tsx | 3 - .../feature_discovery/feature_discovery.tsx | 28 +++-- .../admin_console/feature_discovery/index.tsx | 8 +- .../enterprise_edition_right_panel.test.tsx | 93 ++++++++++++---- .../renew_license_card.test.tsx | 35 +++++- .../workspace-optimization/dashboard.data.tsx | 7 +- .../contact_sales/contact_us.tsx | 7 +- .../overage_users_banner/index.tsx | 6 +- .../overage_users_banner.test.tsx | 12 ++- .../renewal_link/renewal_link.test.tsx | 39 ++++++- .../renewal_link/renewal_link.tsx | 7 +- .../cloud_subscribe_result_modal/error.tsx | 8 +- .../common/hooks/useOpenSalesLink.ts | 34 +++++- .../common/hooks/useOpenZendeskForm.ts | 26 +++++ .../pricing_modal/contact_sales_cta.tsx | 12 +-- .../src/components/pricing_modal/content.tsx | 13 ++- .../pricing_modal/self_hosted_content.tsx | 6 +- .../src/components/purchase_modal/index.ts | 17 ++- .../purchase_modal/purchase_modal.tsx | 13 ++- .../contact_sales_link.tsx | 7 +- .../self_hosted_purchase_modal/error.tsx | 6 +- .../ad_ldap_upsell_banner.tsx | 16 +-- webapp/channels/src/selectors/cloud.ts | 41 ------- .../src/utils/contact_support_sales.ts | 100 ++++++++++++++++++ 33 files changed, 416 insertions(+), 194 deletions(-) create mode 100644 webapp/channels/src/components/common/hooks/useOpenZendeskForm.ts create mode 100644 webapp/channels/src/utils/contact_support_sales.ts diff --git a/webapp/channels/src/components/admin_console/billing/billing_subscriptions/cancel_subscription.tsx b/webapp/channels/src/components/admin_console/billing/billing_subscriptions/cancel_subscription.tsx index 68f5503d66..cf8560ed3b 100644 --- a/webapp/channels/src/components/admin_console/billing/billing_subscriptions/cancel_subscription.tsx +++ b/webapp/channels/src/components/admin_console/billing/billing_subscriptions/cancel_subscription.tsx @@ -5,16 +5,12 @@ import React from 'react'; import {FormattedMessage} from 'react-intl'; import {trackEvent} from 'actions/telemetry_actions'; +import {useOpenCloudZendeskSupportForm} from 'components/common/hooks/useOpenZendeskForm'; import ExternalLink from 'components/external_link'; -type Props = { - cancelAccountLink: any; -} - -const CancelSubscription = (props: Props) => { - const { - cancelAccountLink, - } = props; +const CancelSubscription = () => { + const description = `I am requesting that workspace "${window.location.host}" be deleted`; + const [, contactSupportURL] = useOpenCloudZendeskSupportForm('Request workspace be deleted', description); return (
@@ -33,7 +29,7 @@ const CancelSubscription = (props: Props) => {
trackEvent('cloud_admin', 'click_contact_us')} > diff --git a/webapp/channels/src/components/admin_console/billing/billing_subscriptions/cloud_trial_banner.tsx b/webapp/channels/src/components/admin_console/billing/billing_subscriptions/cloud_trial_banner.tsx index 204495ce90..a62edc1e54 100644 --- a/webapp/channels/src/components/admin_console/billing/billing_subscriptions/cloud_trial_banner.tsx +++ b/webapp/channels/src/components/admin_console/billing/billing_subscriptions/cloud_trial_banner.tsx @@ -24,7 +24,6 @@ import AlertBanner from 'components/alert_banner'; import UpgradeLink from 'components/widgets/links/upgrade_link'; import './cloud_trial_banner.scss'; -import {SalesInquiryIssue} from 'selectors/cloud'; export interface Props { trialEndDate: number; @@ -34,7 +33,7 @@ const CloudTrialBanner = ({trialEndDate}: Props): JSX.Element | null => { const endDate = new Date(trialEndDate); const DISMISSED_DAYS = 10; const {formatMessage} = useIntl(); - const openSalesLink = useOpenSalesLink(SalesInquiryIssue.UpgradeEnterprise); + const [openSalesLink] = useOpenSalesLink(); const dispatch = useDispatch(); const user = useSelector(getCurrentUser); const storedDismissedEndDate = useSelector((state: GlobalState) => getPreference(state, Preferences.CLOUD_TRIAL_BANNER, CloudBanners.UPGRADE_FROM_TRIAL)); diff --git a/webapp/channels/src/components/admin_console/billing/billing_subscriptions/contact_sales_card.tsx b/webapp/channels/src/components/admin_console/billing/billing_subscriptions/contact_sales_card.tsx index 0687b78857..3e5bec63e9 100644 --- a/webapp/channels/src/components/admin_console/billing/billing_subscriptions/contact_sales_card.tsx +++ b/webapp/channels/src/components/admin_console/billing/billing_subscriptions/contact_sales_card.tsx @@ -10,21 +10,19 @@ import {CloudLinks, CloudProducts} from 'utils/constants'; import PrivateCloudSvg from 'components/common/svg_images_components/private_cloud_svg'; import CloudTrialSvg from 'components/common/svg_images_components/cloud_trial_svg'; import {TelemetryProps} from 'components/common/hooks/useOpenPricingModal'; +import useOpenSalesLink from 'components/common/hooks/useOpenSalesLink'; import ExternalLink from 'components/external_link'; type Props = { - contactSalesLink: any; isFreeTrial: boolean; - trialQuestionsLink: any; subscriptionPlan: string | undefined; onUpgradeMattermostCloud: (telemetryProps?: TelemetryProps | undefined) => void; } const ContactSalesCard = (props: Props) => { + const [openSalesLink, contactSalesLink] = useOpenSalesLink(); const { - contactSalesLink, isFreeTrial, - trialQuestionsLink, subscriptionPlan, onUpgradeMattermostCloud, } = props; @@ -145,7 +143,7 @@ const ContactSalesCard = (props: Props) => { {(isFreeTrial || subscriptionPlan === CloudProducts.ENTERPRISE || isCloudLegacyPlan) && trackEvent('cloud_admin', 'click_contact_sales')} > @@ -163,7 +161,7 @@ const ContactSalesCard = (props: Props) => { if (subscriptionPlan === CloudProducts.STARTER) { onUpgradeMattermostCloud({trackingLocation: 'admin_console_subscription_card_upgrade_now_button'}); } else { - window.open(contactSalesLink, '_blank'); + openSalesLink(); } }} className='PrivateCloudCard__actionButton' diff --git a/webapp/channels/src/components/admin_console/billing/billing_subscriptions/index.tsx b/webapp/channels/src/components/admin_console/billing/billing_subscriptions/index.tsx index f4f07ab0f9..ac6bdb6ef1 100644 --- a/webapp/channels/src/components/admin_console/billing/billing_subscriptions/index.tsx +++ b/webapp/channels/src/components/admin_console/billing/billing_subscriptions/index.tsx @@ -13,7 +13,6 @@ import FormattedAdminHeader from 'components/widgets/admin_console/formatted_adm import CloudTrialBanner from 'components/admin_console/billing/billing_subscriptions/cloud_trial_banner'; import CloudFetchError from 'components/cloud_fetch_error'; -import {getCloudContactUsLink, InquiryType, SalesInquiryIssue} from 'selectors/cloud'; import { getSubscriptionProduct, getCloudSubscription as selectCloudSubscription, @@ -63,9 +62,6 @@ const BillingSubscriptions = () => { const isCardExpired = isCustomerCardExpired(useSelector(selectCloudCustomer)); - const contactSalesLink = useSelector(getCloudContactUsLink)(InquiryType.Sales); - const cancelAccountLink = useSelector(getCloudContactUsLink)(InquiryType.Sales, SalesInquiryIssue.CancelAccount); - const trialQuestionsLink = useSelector(getCloudContactUsLink)(InquiryType.Sales, SalesInquiryIssue.TrialQuestions); const trialEndDate = subscription?.trial_end_at || 0; const [showCreditCardBanner, setShowCreditCardBanner] = useState(true); @@ -159,19 +155,12 @@ const BillingSubscriptions = () => { ) : ( )} - {isAnnualProfessionalOrEnterprise && !isFreeTrial ? - : - - } + {isAnnualProfessionalOrEnterprise && !isFreeTrial ? : } }
diff --git a/webapp/channels/src/components/admin_console/billing/billing_subscriptions/limit_reached_banner.test.tsx b/webapp/channels/src/components/admin_console/billing/billing_subscriptions/limit_reached_banner.test.tsx index 0aa08eddb7..66e4356434 100644 --- a/webapp/channels/src/components/admin_console/billing/billing_subscriptions/limit_reached_banner.test.tsx +++ b/webapp/channels/src/components/admin_console/billing/billing_subscriptions/limit_reached_banner.test.tsx @@ -177,7 +177,7 @@ describe('limits_reached_banner', () => { const store = mockStore(state); const spies = makeSpies(); const mockOpenSalesLink = jest.fn(); - spies.useOpenSalesLink.mockReturnValue(mockOpenSalesLink); + spies.useOpenSalesLink.mockReturnValue([mockOpenSalesLink, '']); spies.useGetUsageDeltas.mockReturnValue(someLimitReached); renderWithIntl(); screen.getByText(titleFree); diff --git a/webapp/channels/src/components/admin_console/billing/billing_subscriptions/limit_reached_banner.tsx b/webapp/channels/src/components/admin_console/billing/billing_subscriptions/limit_reached_banner.tsx index d006716bea..666adc3bd0 100644 --- a/webapp/channels/src/components/admin_console/billing/billing_subscriptions/limit_reached_banner.tsx +++ b/webapp/channels/src/components/admin_console/billing/billing_subscriptions/limit_reached_banner.tsx @@ -5,8 +5,6 @@ import React from 'react'; import {useIntl, FormattedMessage} from 'react-intl'; import {useSelector} from 'react-redux'; -import {SalesInquiryIssue} from 'selectors/cloud'; - import {CloudProducts} from 'utils/constants'; import {anyUsageDeltaExceededLimit} from 'utils/limits'; @@ -33,7 +31,7 @@ const LimitReachedBanner = (props: Props) => { const hasDismissedBanner = useSelector(getHasDismissedSystemConsoleLimitReached); - const openSalesLink = useOpenSalesLink(props.product?.sku === CloudProducts.PROFESSIONAL ? SalesInquiryIssue.UpgradeEnterprise : undefined); + const [openSalesLink] = useOpenSalesLink(); const openPricingModal = useOpenPricingModal(); const saveBool = useSaveBool(); if (hasDismissedBanner || !someLimitExceeded || !props.product || (props.product.sku !== CloudProducts.STARTER)) { diff --git a/webapp/channels/src/components/admin_console/billing/billing_subscriptions/limits.tsx b/webapp/channels/src/components/admin_console/billing/billing_subscriptions/limits.tsx index 2798c1374a..3457fbd201 100644 --- a/webapp/channels/src/components/admin_console/billing/billing_subscriptions/limits.tsx +++ b/webapp/channels/src/components/admin_console/billing/billing_subscriptions/limits.tsx @@ -11,8 +11,6 @@ import { getSubscriptionProduct, } from 'mattermost-redux/selectors/entities/cloud'; -import {SalesInquiryIssue} from 'selectors/cloud'; - import {CloudProducts} from 'utils/constants'; import {asGBString, fallbackStarterLimits, hasSomeLimits} from 'utils/limits'; @@ -32,7 +30,7 @@ const Limits = (): JSX.Element | null => { const subscriptionProduct = useSelector(getSubscriptionProduct); const [cloudLimits, limitsLoaded] = useGetLimits(); const usage = useGetUsage(); - const openSalesLink = useOpenSalesLink(SalesInquiryIssue.UpgradeEnterprise); + const [openSalesLink] = useOpenSalesLink(); const openPricingModal = useOpenPricingModal(); if (!subscriptionProduct || !limitsLoaded || !hasSomeLimits(cloudLimits)) { diff --git a/webapp/channels/src/components/admin_console/billing/billing_subscriptions/to_yearly_nudge_banner.tsx b/webapp/channels/src/components/admin_console/billing/billing_subscriptions/to_yearly_nudge_banner.tsx index 1bbf9823b3..3cc1e8aa75 100644 --- a/webapp/channels/src/components/admin_console/billing/billing_subscriptions/to_yearly_nudge_banner.tsx +++ b/webapp/channels/src/components/admin_console/billing/billing_subscriptions/to_yearly_nudge_banner.tsx @@ -10,7 +10,6 @@ import useOpenCloudPurchaseModal from 'components/common/hooks/useOpenCloudPurch import useOpenSalesLink from 'components/common/hooks/useOpenSalesLink'; import AnnouncementBar from 'components/announcement_bar/default_announcement_bar'; -import {SalesInquiryIssue} from 'selectors/cloud'; import {getSubscriptionProduct as selectSubscriptionProduct} from 'mattermost-redux/selectors/entities/cloud'; import {getCurrentUser, isCurrentUserSystemAdmin} from 'mattermost-redux/selectors/entities/users'; import {savePreferences} from 'mattermost-redux/actions/preferences'; @@ -79,7 +78,7 @@ const ToYearlyNudgeBannerDismissable = () => { const ToYearlyNudgeBanner = () => { const {formatMessage} = useIntl(); - const openSalesLink = useOpenSalesLink(SalesInquiryIssue.AboutPurchasing); + const [openSalesLink] = useOpenSalesLink(); const openPurchaseModal = useOpenCloudPurchaseModal({}); const product = useSelector(selectSubscriptionProduct); diff --git a/webapp/channels/src/components/admin_console/billing/delete_workspace/result_modal.tsx b/webapp/channels/src/components/admin_console/billing/delete_workspace/result_modal.tsx index b84c72ee90..bc452d3c57 100644 --- a/webapp/channels/src/components/admin_console/billing/delete_workspace/result_modal.tsx +++ b/webapp/channels/src/components/admin_console/billing/delete_workspace/result_modal.tsx @@ -7,6 +7,7 @@ import {useDispatch, useSelector} from 'react-redux'; import IconMessage from 'components/purchase_modal/icon_message'; import FullScreenModal from 'components/widgets/modals/full_screen_modal'; +import {useOpenCloudZendeskSupportForm} from 'components/common/hooks/useOpenZendeskForm'; import {closeModal} from 'actions/views/modals'; import {isModalOpen} from 'selectors/views/modals'; @@ -14,9 +15,6 @@ import {GlobalState} from 'types/store'; import './result_modal.scss'; -import useOpenSalesLink from 'components/common/hooks/useOpenSalesLink'; -import {InquiryType} from 'selectors/cloud'; - type Props = { onHide?: () => void; icon: JSX.Element; @@ -33,7 +31,7 @@ type Props = { export default function ResultModal(props: Props) { const dispatch = useDispatch(); - const openContactUs = useOpenSalesLink(undefined, InquiryType.Technical); + const [openContactSupport] = useOpenCloudZendeskSupportForm('Delete workspace', ''); const isResultModalOpen = useSelector((state: GlobalState) => isModalOpen(state, props.identifier), @@ -64,14 +62,13 @@ export default function ResultModal(props: Props) { buttonHandler={props.primaryButtonHandler} className={'success'} formattedTertiaryButonText={ - props.contactSupportButtonVisible ? + props.contactSupportButtonVisible ? ( : - undefined + />) : undefined } - tertiaryButtonHandler={props.contactSupportButtonVisible ? openContactUs : undefined} + tertiaryButtonHandler={props.contactSupportButtonVisible ? openContactSupport : undefined} />
diff --git a/webapp/channels/src/components/admin_console/feature_discovery/feature_discovery.test.tsx b/webapp/channels/src/components/admin_console/feature_discovery/feature_discovery.test.tsx index 2b8e5d19b2..e8589a0c09 100644 --- a/webapp/channels/src/components/admin_console/feature_discovery/feature_discovery.test.tsx +++ b/webapp/channels/src/components/admin_console/feature_discovery/feature_discovery.test.tsx @@ -17,7 +17,6 @@ describe('components/feature_discovery', () => { { { }); } + contactSalesFunc = () => { + const {customer, isCloud} = this.props; + const customerEmail = customer?.email || ''; + const firstName = customer?.contact_first_name || ''; + const lastName = customer?.contact_last_name || ''; + const companyName = customer?.name || ''; + const utmMedium = isCloud ? 'in-product-cloud' : 'in-product'; + goToMattermostContactSalesForm(firstName, lastName, companyName, customerEmail, 'mattermost', utmMedium); + } + renderPostTrialCta = () => { const { minimumSKURequiredForFeature, @@ -110,7 +122,7 @@ export default class FeatureDiscovery extends React.PureComponent data-testid='featureDiscovery_primaryCallToAction' onClick={() => { trackEvent(TELEMETRY_CATEGORIES.SELF_HOSTED_ADMIN, 'click_enterprise_contact_sales_feature_discovery'); - window.open(LicenseLinks.CONTACT_SALES, '_blank'); + this.contactSalesFunc(); }} > hadPrevCloudTrial, isPaidSubscription, minimumSKURequiredForFeature, - contactSalesLink, } = this.props; const canRequestCloudFreeTrial = isCloud && !isCloudTrial && !hadPrevCloudTrial && !isPaidSubscription; @@ -217,11 +228,10 @@ export default class FeatureDiscovery extends React.PureComponent onClick={() => { if (isCloud) { trackEvent(TELEMETRY_CATEGORIES.CLOUD_ADMIN, 'click_enterprise_contact_sales_feature_discovery'); - window.open(contactSalesLink, '_blank'); } else { trackEvent(TELEMETRY_CATEGORIES.SELF_HOSTED_ADMIN, 'click_enterprise_contact_sales_feature_discovery'); - window.open(LicenseLinks.CONTACT_SALES, '_blank'); } + this.contactSalesFunc(); }} > { const license = { IsLicensed: 'true', @@ -28,8 +61,11 @@ describe('components/admin_console/license_settings/enterprise_edition/enterpris } as EnterpriseEditionProps; test('should render for no Gov no Trial no Enterprise', () => { + const store = mockStore(initialState); const wrapper = mountWithIntl( - , + + + , ); expect(wrapper.find('.upgrade-title').text()).toEqual('Upgrade to the Enterprise Plan'); @@ -43,11 +79,14 @@ describe('components/admin_console/license_settings/enterprise_edition/enterpris }); test('should render for Gov no Trial no Enterprise', () => { + const store = mockStore(initialState); const wrapper = mountWithIntl( - , + + + , ); expect(wrapper.find('.upgrade-title').text()).toEqual('Upgrade to the Enterprise Gov Plan'); @@ -61,11 +100,14 @@ describe('components/admin_console/license_settings/enterprise_edition/enterpris }); test('should render for Enterprise no Trial', () => { + const store = mockStore(initialState); const wrapper = mountWithIntl( - , + + + , ); expect(wrapper.find('.upgrade-title').text()).toEqual('Need to increase your headcount?'); @@ -73,11 +115,14 @@ describe('components/admin_console/license_settings/enterprise_edition/enterpris }); test('should render for E20 no Trial', () => { + const store = mockStore(initialState); const wrapper = mountWithIntl( - , + + + , ); expect(wrapper.find('.upgrade-title').text()).toEqual('Need to increase your headcount?'); @@ -85,11 +130,14 @@ describe('components/admin_console/license_settings/enterprise_edition/enterpris }); test('should render for Trial no Gov', () => { + const store = mockStore(initialState); const wrapper = mountWithIntl( - , + + + , ); expect(wrapper.find('.upgrade-title').text()).toEqual('Purchase the Enterprise Plan'); @@ -97,11 +145,14 @@ describe('components/admin_console/license_settings/enterprise_edition/enterpris }); test('should render for Trial Gov', () => { + const store = mockStore(initialState); const wrapper = mountWithIntl( - , + + + , ); expect(wrapper.find('.upgrade-title').text()).toEqual('Purchase the Enterprise Gov Plan'); diff --git a/webapp/channels/src/components/admin_console/license_settings/renew_license_card/renew_license_card.test.tsx b/webapp/channels/src/components/admin_console/license_settings/renew_license_card/renew_license_card.test.tsx index eb43a3cf0f..c52e8272d7 100644 --- a/webapp/channels/src/components/admin_console/license_settings/renew_license_card/renew_license_card.test.tsx +++ b/webapp/channels/src/components/admin_console/license_settings/renew_license_card/renew_license_card.test.tsx @@ -12,6 +12,37 @@ import mockStore from 'tests/test_store'; import RenewalLicenseCard from './renew_license_card'; +const initialState = { + views: { + announcementBar: { + announcementBarState: { + announcementBarCount: 1, + }, + }, + }, + entities: { + general: { + config: { + CWSURL: '', + }, + license: { + IsLicensed: 'true', + Cloud: 'true', + }, + }, + users: { + currentUserId: 'current_user_id', + profiles: { + current_user_id: {roles: 'system_user'}, + }, + }, + preferences: { + myPreferences: {}, + }, + cloud: {}, + }, +}; + const actImmediate = (wrapper: ReactWrapper) => act( () => @@ -47,7 +78,7 @@ describe('components/RenewalLicenseCard', () => { }); }); getRenewalLinkSpy.mockImplementation(() => promise); - const store = mockStore({}); + const store = mockStore(initialState); const wrapper = mountWithIntl(); // wait for the promise to resolve and component to update @@ -64,7 +95,7 @@ describe('components/RenewalLicenseCard', () => { reject(new Error('License cannot be renewed from portal')); }); getRenewalLinkSpy.mockImplementation(() => promise); - const store = mockStore({}); + const store = mockStore(initialState); const wrapper = mountWithIntl(); // wait for the promise to resolve and component to update diff --git a/webapp/channels/src/components/admin_console/workspace-optimization/dashboard.data.tsx b/webapp/channels/src/components/admin_console/workspace-optimization/dashboard.data.tsx index b9477f36de..dd5ee9b565 100644 --- a/webapp/channels/src/components/admin_console/workspace-optimization/dashboard.data.tsx +++ b/webapp/channels/src/components/admin_console/workspace-optimization/dashboard.data.tsx @@ -18,8 +18,9 @@ import {getLicense} from 'mattermost-redux/selectors/entities/general'; import {GlobalState} from '@mattermost/types/store'; -import {CloudLinks, ConsolePages, DocLinks, LicenseLinks} from 'utils/constants'; +import {CloudLinks, ConsolePages, DocLinks} from 'utils/constants'; import {daysToLicenseExpire, isEnterpriseOrE20License, getIsStarterLicense} from '../../../utils/license_utils'; +import useOpenSalesLink from 'components/common/hooks/useOpenSalesLink'; export type DataModel = { [key: string]: { @@ -84,8 +85,10 @@ const useMetricsData = () => { const isEnterpriseLicense = isEnterpriseOrE20License(license); const isStarterLicense = getIsStarterLicense(license); + const [, contactSalesLink] = useOpenSalesLink(); + const trialOrEnterpriseCtaConfig = { - configUrl: canStartTrial ? ConsolePages.LICENSE : LicenseLinks.CONTACT_SALES, + configUrl: canStartTrial ? ConsolePages.LICENSE : contactSalesLink, configText: canStartTrial ? formatMessage({id: 'admin.reporting.workspace_optimization.cta.startTrial', defaultMessage: 'Start trial'}) : formatMessage({id: 'admin.reporting.workspace_optimization.cta.upgradeLicense', defaultMessage: 'Contact sales'}), }; diff --git a/webapp/channels/src/components/announcement_bar/contact_sales/contact_us.tsx b/webapp/channels/src/components/announcement_bar/contact_sales/contact_us.tsx index 48abe4a4dd..74b576192d 100644 --- a/webapp/channels/src/components/announcement_bar/contact_sales/contact_us.tsx +++ b/webapp/channels/src/components/announcement_bar/contact_sales/contact_us.tsx @@ -6,8 +6,9 @@ import React from 'react'; import {FormattedMessage} from 'react-intl'; import {trackEvent} from 'actions/telemetry_actions'; +import useOpenSalesLink from 'components/common/hooks/useOpenSalesLink'; + import './contact_us.scss'; -import {LicenseLinks} from '../../../utils/constants'; export interface Props { buttonTextElement?: JSX.Element; @@ -16,10 +17,12 @@ export interface Props { } const ContactUsButton: React.FC = (props: Props) => { + const [openContactSales] = useOpenSalesLink(); + const handleContactUsLinkClick = async (e: React.MouseEvent) => { e.preventDefault(); trackEvent('admin', props.eventID || 'in_trial_contact_sales'); - window.open(LicenseLinks.CONTACT_SALES, '_blank'); + openContactSales(); }; return ( diff --git a/webapp/channels/src/components/announcement_bar/overage_users_banner/index.tsx b/webapp/channels/src/components/announcement_bar/overage_users_banner/index.tsx index 176af1dbd2..d22fe6389f 100644 --- a/webapp/channels/src/components/announcement_bar/overage_users_banner/index.tsx +++ b/webapp/channels/src/components/announcement_bar/overage_users_banner/index.tsx @@ -15,7 +15,8 @@ import {savePreferences} from 'mattermost-redux/actions/preferences'; import {makeGetCategory} from 'mattermost-redux/selectors/entities/preferences'; import {PreferenceType} from '@mattermost/types/preferences'; import {useExpandOverageUsersCheck} from 'components/common/hooks/useExpandOverageUsersCheck'; -import {LicenseLinks, StatTypes, Preferences, AnnouncementBarTypes} from 'utils/constants'; +import useOpenSalesLink from 'components/common/hooks/useOpenSalesLink'; +import {StatTypes, Preferences, AnnouncementBarTypes} from 'utils/constants'; import './overage_users_banner.scss'; @@ -34,6 +35,7 @@ const adminHasDismissed = ({preferenceName, overagePreferences, isWarningBanner} }; const OverageUsersBanner = () => { + const [openContactSales] = useOpenSalesLink(); const dispatch = useDispatch(); const stats = useSelector((state: GlobalState) => state.entities.admin.analytics) || {}; const isAdmin = useSelector(isCurrentUserSystemAdmin); @@ -90,7 +92,7 @@ const OverageUsersBanner = () => { const handleContactSalesClick = (e: React.MouseEvent) => { e.preventDefault(); trackEventFn('Contact Sales'); - window.open(LicenseLinks.CONTACT_SALES, '_blank'); + openContactSales(); }; const handleClick = isExpandable ? handleUpdateSeatsSelfServeClick : handleContactSalesClick; diff --git a/webapp/channels/src/components/announcement_bar/overage_users_banner/overage_users_banner.test.tsx b/webapp/channels/src/components/announcement_bar/overage_users_banner/overage_users_banner.test.tsx index 212c9dadae..dedd30a7c9 100644 --- a/webapp/channels/src/components/announcement_bar/overage_users_banner/overage_users_banner.test.tsx +++ b/webapp/channels/src/components/announcement_bar/overage_users_banner/overage_users_banner.test.tsx @@ -7,7 +7,7 @@ import {fireEvent, screen} from '@testing-library/react'; import {DeepPartial} from '@mattermost/types/utilities'; import {GlobalState} from 'types/store'; import {General} from 'mattermost-redux/constants'; -import {LicenseLinks, OverActiveUserLimits, Preferences, StatTypes} from 'utils/constants'; +import {OverActiveUserLimits, Preferences, StatTypes} from 'utils/constants'; import {renderWithIntlAndStore} from 'tests/react_testing_utils'; import {savePreferences} from 'mattermost-redux/actions/preferences'; import {trackEvent} from 'actions/telemetry_actions'; @@ -249,7 +249,10 @@ describe('components/overage_users_banner', () => { fireEvent.click(screen.getByText(contactSalesTextLink)); expect(windowSpy).toBeCalledTimes(1); - expect(windowSpy).toBeCalledWith(LicenseLinks.CONTACT_SALES, '_blank'); + + // only the email is encoded and other params are empty. See logic for useOpenSalesLink hook + const salesLinkWithEncodedParams = 'https://mattermost.com/contact-sales/?qk=&qp=&qw=&qx=dGVzdEBtYXR0ZXJtb3N0LmNvbQ==&utm_source=mattermost&utm_medium=in-product'; + expect(windowSpy).toBeCalledWith(salesLinkWithEncodedParams, '_blank'); expect(trackEvent).toBeCalledTimes(1); expect(trackEvent).toBeCalledWith('insights', 'click_true_up_warning', { cta: 'Contact Sales', @@ -368,7 +371,10 @@ describe('components/overage_users_banner', () => { fireEvent.click(screen.getByText(contactSalesTextLink)); expect(windowSpy).toBeCalledTimes(1); - expect(windowSpy).toBeCalledWith(LicenseLinks.CONTACT_SALES, '_blank'); + + // only the email is encoded and other params are empty. See logic for useOpenSalesLink hook + const salesLinkWithEncodedParams = 'https://mattermost.com/contact-sales/?qk=&qp=&qw=&qx=dGVzdEBtYXR0ZXJtb3N0LmNvbQ==&utm_source=mattermost&utm_medium=in-product'; + expect(windowSpy).toBeCalledWith(salesLinkWithEncodedParams, '_blank'); expect(trackEvent).toBeCalledTimes(1); expect(trackEvent).toBeCalledWith('insights', 'click_true_up_error', { cta: 'Contact Sales', diff --git a/webapp/channels/src/components/announcement_bar/renewal_link/renewal_link.test.tsx b/webapp/channels/src/components/announcement_bar/renewal_link/renewal_link.test.tsx index 7582add168..9dae6a38d0 100644 --- a/webapp/channels/src/components/announcement_bar/renewal_link/renewal_link.test.tsx +++ b/webapp/channels/src/components/announcement_bar/renewal_link/renewal_link.test.tsx @@ -3,13 +3,46 @@ import React from 'react'; import {ReactWrapper} from 'enzyme'; +import {Provider} from 'react-redux'; import {act} from 'react-dom/test-utils'; import {Client4} from 'mattermost-redux/client'; import {mountWithIntl} from 'tests/helpers/intl-test-helper'; +import mockStore from 'tests/test_store'; import RenewalLink from './renewal_link'; +const initialState = { + views: { + announcementBar: { + announcementBarState: { + announcementBarCount: 1, + }, + }, + }, + entities: { + general: { + config: { + CWSURL: '', + }, + license: { + IsLicensed: 'true', + Cloud: 'true', + }, + }, + users: { + currentUserId: 'current_user_id', + profiles: { + current_user_id: {roles: 'system_user'}, + }, + }, + preferences: { + myPreferences: {}, + }, + cloud: {}, + }, +}; + const actImmediate = (wrapper: ReactWrapper) => act( () => @@ -40,7 +73,8 @@ describe('components/RenewalLink', () => { }); }); getRenewalLinkSpy.mockImplementation(() => promise); - const wrapper = mountWithIntl(); + const store = mockStore(initialState); + const wrapper = mountWithIntl(); // wait for the promise to resolve and component to update await actImmediate(wrapper); @@ -54,7 +88,8 @@ describe('components/RenewalLink', () => { reject(new Error('License cannot be renewed from portal')); }); getRenewalLinkSpy.mockImplementation(() => promise); - const wrapper = mountWithIntl(); + const store = mockStore(initialState); + const wrapper = mountWithIntl(); // wait for the promise to resolve and component to update await actImmediate(wrapper); diff --git a/webapp/channels/src/components/announcement_bar/renewal_link/renewal_link.tsx b/webapp/channels/src/components/announcement_bar/renewal_link/renewal_link.tsx index 3ca79b1e11..dfae9f3ea1 100644 --- a/webapp/channels/src/components/announcement_bar/renewal_link/renewal_link.tsx +++ b/webapp/channels/src/components/announcement_bar/renewal_link/renewal_link.tsx @@ -11,9 +11,9 @@ import {trackEvent} from 'actions/telemetry_actions'; import {ModalData} from 'types/actions'; import { - LicenseLinks, ModalIdentifiers, } from 'utils/constants'; +import useOpenSalesLink from 'components/common/hooks/useOpenSalesLink'; import NoInternetConnection from '../no_internet_connection/no_internet_connection'; @@ -31,6 +31,9 @@ export interface RenewalLinkProps { const RenewalLink = (props: RenewalLinkProps) => { const [renewalLink, setRenewalLink] = useState(''); const [manualInterventionRequired, setManualInterventionRequired] = useState(false); + + const [openContactSales] = useOpenSalesLink(); + useEffect(() => { Client4.getRenewalLink().then(({renewal_link: renewalLinkParam}) => { try { @@ -55,7 +58,7 @@ const RenewalLink = (props: RenewalLinkProps) => { } window.open(renewalLink, '_blank'); } else if (manualInterventionRequired) { - window.open(LicenseLinks.CONTACT_SALES, '_blank'); + openContactSales(); } else { showConnectionErrorModal(); } diff --git a/webapp/channels/src/components/cloud_subscribe_result_modal/error.tsx b/webapp/channels/src/components/cloud_subscribe_result_modal/error.tsx index 0b61d3598e..2340430c02 100644 --- a/webapp/channels/src/components/cloud_subscribe_result_modal/error.tsx +++ b/webapp/channels/src/components/cloud_subscribe_result_modal/error.tsx @@ -13,9 +13,8 @@ import PaymentFailedSvg from 'components/common/svg_images_components/payment_fa import IconMessage from 'components/purchase_modal/icon_message'; import FullScreenModal from 'components/widgets/modals/full_screen_modal'; -import useOpenSalesLink from 'components/common/hooks/useOpenSalesLink'; +import {useOpenCloudZendeskSupportForm} from 'components/common/hooks/useOpenZendeskForm'; -import {InquiryType} from 'selectors/cloud'; import {closeModal} from 'actions/views/modals'; import {ModalIdentifiers} from 'utils/constants'; import {isModalOpen} from 'selectors/views/modals'; @@ -31,7 +30,8 @@ type Props = { function ErrorModal(props: Props) { const dispatch = useDispatch(); const subscriptionProduct = useSelector(getSubscriptionProduct); - const openContactUs = useOpenSalesLink(undefined, InquiryType.Technical); + + const [openContactSupport] = useOpenCloudZendeskSupportForm('Cloud Subscription', ''); const isSuccessModalOpen = useSelector((state: GlobalState) => isModalOpen(state, ModalIdentifiers.ERROR_MODAL), @@ -97,7 +97,7 @@ function ErrorModal(props: Props) { } /> } - tertiaryButtonHandler={openContactUs} + tertiaryButtonHandler={openContactSupport} buttonHandler={onBackButtonPress} className={'success'} /> diff --git a/webapp/channels/src/components/common/hooks/useOpenSalesLink.ts b/webapp/channels/src/components/common/hooks/useOpenSalesLink.ts index aecb58844f..4dbe44d0ca 100644 --- a/webapp/channels/src/components/common/hooks/useOpenSalesLink.ts +++ b/webapp/channels/src/components/common/hooks/useOpenSalesLink.ts @@ -3,11 +3,35 @@ import {useSelector} from 'react-redux'; -import {getCloudContactUsLink, InquiryType, SalesInquiryIssue} from 'selectors/cloud'; +import {getCloudCustomer, isCurrentLicenseCloud} from 'mattermost-redux/selectors/entities/cloud'; +import {getCurrentUser} from 'mattermost-redux/selectors/entities/users'; +import {buildMMURL, goToMattermostContactSalesForm} from 'utils/contact_support_sales'; +import {LicenseLinks} from 'utils/constants'; -export default function useOpenSalesLink(issue?: SalesInquiryIssue, inquireType: InquiryType = InquiryType.Sales) { - const contactSalesLink = useSelector(getCloudContactUsLink)(inquireType, issue); +export default function useOpenSalesLink(): [() => void, string] { + const isCloud = useSelector(isCurrentLicenseCloud); + const customer = useSelector(getCloudCustomer); + const currentUser = useSelector(getCurrentUser); + let customerEmail = ''; + let firstName = ''; + let lastName = ''; + let companyName = ''; + const utmSource = 'mattermost'; + let utmMedium = 'in-product'; - return () => window.open(contactSalesLink, '_blank'); + if (isCloud && customer) { + customerEmail = customer.email || ''; + firstName = customer.contact_first_name || ''; + lastName = customer.contact_last_name || ''; + companyName = customer.name || ''; + utmMedium = 'in-product-cloud'; + } else { + customerEmail = currentUser.email || ''; + } + + const contactSalesLink = buildMMURL(LicenseLinks.CONTACT_SALES, firstName, lastName, companyName, customerEmail, utmSource, utmMedium); + const goToSalesLinkFunc = () => { + goToMattermostContactSalesForm(firstName, lastName, companyName, customerEmail, utmSource, utmMedium); + }; + return [goToSalesLinkFunc, contactSalesLink]; } - diff --git a/webapp/channels/src/components/common/hooks/useOpenZendeskForm.ts b/webapp/channels/src/components/common/hooks/useOpenZendeskForm.ts new file mode 100644 index 0000000000..16df9d9a02 --- /dev/null +++ b/webapp/channels/src/components/common/hooks/useOpenZendeskForm.ts @@ -0,0 +1,26 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {useSelector} from 'react-redux'; + +import {getCloudCustomer} from 'mattermost-redux/selectors/entities/cloud'; +import {getCurrentUser} from 'mattermost-redux/selectors/entities/users'; +import {getCloudSupportLink, getSelfHostedSupportLink, goToCloudSupportForm, goToSelfHostedSupportForm} from 'utils/contact_support_sales'; + +export function useOpenCloudZendeskSupportForm(subject: string, description: string): [() => void, string] { + const customer = useSelector(getCloudCustomer); + const customerEmail = customer?.email || ''; + + const url = getCloudSupportLink(customerEmail, subject, description, window.location.host); + + return [() => goToCloudSupportForm(customerEmail, subject, description, window.location.host), url]; +} + +export function useOpenSelfHostedZendeskSupportForm(subject: string): [() => void, string] { + const currentUser = useSelector(getCurrentUser); + const customerEmail = currentUser.email || ''; + + const url = getSelfHostedSupportLink(customerEmail, subject); + + return [() => goToSelfHostedSupportForm(customerEmail, subject), url]; +} diff --git a/webapp/channels/src/components/pricing_modal/contact_sales_cta.tsx b/webapp/channels/src/components/pricing_modal/contact_sales_cta.tsx index 1a0c47ed2a..66e05d0947 100644 --- a/webapp/channels/src/components/pricing_modal/contact_sales_cta.tsx +++ b/webapp/channels/src/components/pricing_modal/contact_sales_cta.tsx @@ -11,8 +11,7 @@ import {trackEvent} from 'actions/telemetry_actions'; import useOpenSalesLink from 'components/common/hooks/useOpenSalesLink'; -import {LicenseLinks, TELEMETRY_CATEGORIES} from 'utils/constants'; -import {SalesInquiryIssue} from 'selectors/cloud'; +import {TELEMETRY_CATEGORIES} from 'utils/constants'; const StyledA = styled.a` color: var(--denim-button-bg); @@ -27,11 +26,7 @@ text-align: center; function ContactSalesCTA() { const {formatMessage} = useIntl(); - const openSalesLink = useOpenSalesLink(SalesInquiryIssue.UpgradeEnterprise); - - const openSelfHostedLink = () => { - window.open(LicenseLinks.CONTACT_SALES, '_blank'); - }; + const [openSalesLink] = useOpenSalesLink(); const isCloud = useSelector(isCurrentLicenseCloud); @@ -42,11 +37,10 @@ function ContactSalesCTA() { e.preventDefault(); if (isCloud) { trackEvent(TELEMETRY_CATEGORIES.CLOUD_PRICING, 'click_enterprise_contact_sales'); - openSalesLink(); } else { trackEvent('self_hosted_pricing', 'click_enterprise_contact_sales'); - openSelfHostedLink(); } + openSalesLink(); }} > {formatMessage({id: 'pricing_modal.btn.contactSalesForQuote', defaultMessage: 'Contact Sales'})} diff --git a/webapp/channels/src/components/pricing_modal/content.tsx b/webapp/channels/src/components/pricing_modal/content.tsx index 7dc7d8dcfc..e0f55999fe 100644 --- a/webapp/channels/src/components/pricing_modal/content.tsx +++ b/webapp/channels/src/components/pricing_modal/content.tsx @@ -10,8 +10,6 @@ import {CloudLinks, CloudProducts, LicenseSkus, ModalIdentifiers, MattermostFeat import {fallbackStarterLimits, asGBString, hasSomeLimits} from 'utils/limits'; import {findOnlyYearlyProducts, findProductBySku} from 'utils/products'; -import {getCloudContactUsLink, InquiryType, SalesInquiryIssue} from 'selectors/cloud'; - import {trackEvent} from 'actions/telemetry_actions'; import {closeModal, openModal} from 'actions/views/modals'; import {subscribeCloudSubscription} from 'actions/cloud'; @@ -38,6 +36,8 @@ import useOpenCloudPurchaseModal from 'components/common/hooks/useOpenCloudPurch import useOpenPricingModal from 'components/common/hooks/useOpenPricingModal'; import useOpenDowngradeModal from 'components/common/hooks/useOpenDowngradeModal'; +import useOpenSalesLink from 'components/common/hooks/useOpenSalesLink'; +import {useOpenCloudZendeskSupportForm} from 'components/common/hooks/useOpenZendeskForm'; import ExternalLink from 'components/external_link'; import DowngradeTeamRemovalModal from './downgrade_team_removal_modal'; @@ -64,15 +64,12 @@ function Content(props: ContentProps) { const openPricingModalBackAction = useOpenPricingModal(); const isAdmin = useSelector(isCurrentUserSystemAdmin); - const contactSalesLink = useSelector(getCloudContactUsLink)(InquiryType.Sales, SalesInquiryIssue.UpgradeEnterprise); const subscription = useSelector(selectCloudSubscription); const currentProduct = useSelector(selectSubscriptionProduct); const products = useSelector(selectCloudProducts); const yearlyProducts = findOnlyYearlyProducts(products || {}); // pricing modal should now only show yearly products - const contactSupportLink = useSelector(getCloudContactUsLink)(InquiryType.Technical); - const currentSubscriptionIsMonthly = currentProduct?.recurring_interval === RecurringIntervals.MONTH; const isEnterprise = currentProduct?.sku === CloudProducts.ENTERPRISE; const isEnterpriseTrial = subscription?.is_free_trial === 'true'; @@ -124,6 +121,8 @@ function Content(props: ContentProps) { const freeTierText = (!isStarter && !currentSubscriptionIsMonthly) ? formatMessage({id: 'pricing_modal.btn.contactSupport', defaultMessage: 'Contact Support'}) : formatMessage({id: 'pricing_modal.btn.downgrade', defaultMessage: 'Downgrade'}); const adminProfessionalTierText = currentSubscriptionIsMonthlyProfessional ? formatMessage({id: 'pricing_modal.btn.switch_to_annual', defaultMessage: 'Switch to annual billing'}) : formatMessage({id: 'pricing_modal.btn.upgrade', defaultMessage: 'Upgrade'}); + const [openContactSales] = useOpenSalesLink(); + const [openContactSupport] = useOpenCloudZendeskSupportForm('Workspace downgrade', ''); const openCloudPurchaseModal = useOpenCloudPurchaseModal({}); const openCloudDelinquencyModal = useOpenCloudPurchaseModal({ isDelinquencyModal: true, @@ -239,7 +238,7 @@ function Content(props: ContentProps) { return { action: () => { trackEvent(TELEMETRY_CATEGORIES.CLOUD_PRICING, 'click_enterprise_contact_sales'); - window.open(contactSalesLink, '_blank'); + openContactSales(); }, text: formatMessage({id: 'pricing_modal.btn.contactSales', defaultMessage: 'Contact Sales'}), customClass: ButtonCustomiserClasses.active, @@ -350,7 +349,7 @@ function Content(props: ContentProps) { buttonDetails={{ action: () => { if (!isStarter && !currentSubscriptionIsMonthly) { - window.open(contactSupportLink, '_blank'); + openContactSupport(); return; } diff --git a/webapp/channels/src/components/pricing_modal/self_hosted_content.tsx b/webapp/channels/src/components/pricing_modal/self_hosted_content.tsx index c573b10c4a..9edb86d824 100644 --- a/webapp/channels/src/components/pricing_modal/self_hosted_content.tsx +++ b/webapp/channels/src/components/pricing_modal/self_hosted_content.tsx @@ -6,7 +6,7 @@ import {Modal} from 'react-bootstrap'; import {useIntl} from 'react-intl'; import {useDispatch, useSelector} from 'react-redux'; -import {CloudLinks, LicenseLinks, ModalIdentifiers, SelfHostedProducts, LicenseSkus, TELEMETRY_CATEGORIES, RecurringIntervals} from 'utils/constants'; +import {CloudLinks, ModalIdentifiers, SelfHostedProducts, LicenseSkus, TELEMETRY_CATEGORIES, RecurringIntervals} from 'utils/constants'; import {findSelfHostedProductBySku} from 'utils/hosted_customer'; import {trackEvent} from 'actions/telemetry_actions'; @@ -27,6 +27,7 @@ import StartTrialBtn from 'components/learn_more_trial_modal/start_trial_btn'; import ExternalLink from 'components/external_link'; import useCanSelfHostedSignup from 'components/common/hooks/useCanSelfHostedSignup'; +import useOpenSalesLink from 'components/common/hooks/useOpenSalesLink'; import { useControlAirGappedSelfHostedPurchaseModal, @@ -89,6 +90,7 @@ function SelfHostedContent(props: ContentProps) { const isEnterprise = license.SkuShortName === LicenseSkus.Enterprise; const isPostSelfHostedEnterpriseTrial = prevSelfHostedTrialLicense.IsLicensed === 'true'; + const [openContactSales] = useOpenSalesLink(); const controlScreeningInProgressModal = useControlScreeningInProgressModal(); const controlAirgappedModal = useControlAirGappedSelfHostedPurchaseModal(); @@ -287,7 +289,7 @@ function SelfHostedContent(props: ContentProps) { buttonDetails={(isPostSelfHostedEnterpriseTrial || !isAdmin) ? { action: () => { trackEvent('self_hosted_pricing', 'click_enterprise_contact_sales'); - window.open(LicenseLinks.CONTACT_SALES, '_blank'); + openContactSales(); }, text: formatMessage({id: 'pricing_modal.btn.contactSales', defaultMessage: 'Contact Sales'}), customClass: ButtonCustomiserClasses.active, diff --git a/webapp/channels/src/components/purchase_modal/index.ts b/webapp/channels/src/components/purchase_modal/index.ts index be38d6167d..0285722adf 100644 --- a/webapp/channels/src/components/purchase_modal/index.ts +++ b/webapp/channels/src/components/purchase_modal/index.ts @@ -19,7 +19,7 @@ import {GlobalState} from 'types/store'; import {BillingDetails} from 'types/cloud/sku'; import {isModalOpen} from 'selectors/views/modals'; -import {getCloudContactUsLink, InquiryType, getCloudDelinquentInvoices, isCloudDelinquencyGreaterThan90Days} from 'selectors/cloud'; +import {getCloudDelinquentInvoices, isCloudDelinquencyGreaterThan90Days} from 'selectors/cloud'; import {isDevModeEnabled} from 'selectors/general'; import {ModalIdentifiers} from 'utils/constants'; @@ -29,6 +29,7 @@ import {completeStripeAddPaymentMethod, subscribeCloudSubscription} from 'action import {ModalData} from 'types/actions'; import withGetCloudSubscription from 'components/common/hocs/cloud/with_get_cloud_subscription'; import {findOnlyYearlyProducts} from 'utils/products'; +import {getCloudContactSalesLink, getCloudSupportLink} from 'utils/contact_support_sales'; const PurchaseModal = makeAsyncComponent('PurchaseModal', React.lazy(() => import('./purchase_modal'))); @@ -39,19 +40,27 @@ function mapStateToProps(state: GlobalState) { const products = state.entities.cloud!.products; const yearlyProducts = findOnlyYearlyProducts(products || {}); + const customer = state.entities.cloud.customer; + const customerEmail = customer?.email || ''; + const firstName = customer?.contact_first_name || ''; + const lastName = customer?.contact_last_name || ''; + const companyName = customer?.name || ''; + const contactSalesLink = getCloudContactSalesLink(firstName, lastName, companyName, customerEmail, 'mattermost', 'in-product-cloud'); + const contactSupportLink = getCloudSupportLink(customerEmail, 'Cloud purchase', '', window.location.host); + return { show: isModalOpen(state, ModalIdentifiers.CLOUD_PURCHASE), products, yearlyProducts, isDevMode: isDevModeEnabled(state), - contactSupportLink: getCloudContactUsLink(state)(InquiryType.Technical), + contactSupportLink, invoices: getCloudDelinquentInvoices(state), isCloudDelinquencyGreaterThan90Days: isCloudDelinquencyGreaterThan90Days(state), isFreeTrial: subscription?.is_free_trial === 'true', isComplianceBlocked: subscription?.compliance_blocked === 'true', - contactSalesLink: getCloudContactUsLink(state)(InquiryType.Sales), + contactSalesLink, productId: subscription?.product_id, - customer: state.entities.cloud.customer, + customer, currentTeam: getCurrentTeam(state), theme: getTheme(state), isDelinquencyModal, diff --git a/webapp/channels/src/components/purchase_modal/purchase_modal.tsx b/webapp/channels/src/components/purchase_modal/purchase_modal.tsx index 36b39a3ab0..3fdfe6f319 100644 --- a/webapp/channels/src/components/purchase_modal/purchase_modal.tsx +++ b/webapp/channels/src/components/purchase_modal/purchase_modal.tsx @@ -18,7 +18,6 @@ import ComplianceScreenFailedSvg from 'components/common/svg_images_components/a import AddressForm from 'components/payment_form/address_form'; import {t} from 'utils/i18n'; -import {Address, CloudCustomer, Product, Invoice, areShippingDetailsValid, Feedback} from '@mattermost/types/cloud'; import {ActionResult} from 'mattermost-redux/types/actions'; import {localizeMessage, getNextBillingDate, getBlankAddressWithCountry} from 'utils/utils'; @@ -34,6 +33,7 @@ import { ModalIdentifiers, RecurringIntervals, } from 'utils/constants'; +import {goToMattermostContactSalesForm} from 'utils/contact_support_sales'; import PaymentDetails from 'components/admin_console/billing/payment_details'; import {STRIPE_CSS_SRC, STRIPE_PUBLIC_KEY} from 'components/payment_form/stripe'; @@ -54,6 +54,8 @@ import {ModalData} from 'types/actions'; import {Theme} from 'mattermost-redux/selectors/entities/preferences'; +import {Address, CloudCustomer, Product, Invoice, areShippingDetailsValid, Feedback} from '@mattermost/types/cloud'; + import {areBillingDetailsValid, BillingDetails} from '../../types/cloud/sku'; import {Team} from '@mattermost/types/teams'; @@ -463,6 +465,7 @@ class PurchaseModal extends React.PureComponent { } confirmSwitchToAnnual = () => { + const {customer} = this.props; this.props.actions.openModal({ modalId: ModalIdentifiers.CONFIRM_SWITCH_TO_YEARLY, dialogType: SwitchToYearlyPlanConfirmModal, @@ -476,7 +479,11 @@ class PurchaseModal extends React.PureComponent { TELEMETRY_CATEGORIES.CLOUD_ADMIN, 'confirm_switch_to_annual_click_contact_sales', ); - window.open(this.props.contactSalesLink, '_blank'); + const customerEmail = customer?.email || ''; + const firstName = customer?.contact_first_name || ''; + const lastName = customer?.contact_last_name || ''; + const companyName = customer?.name || ''; + goToMattermostContactSalesForm(firstName, lastName, companyName, customerEmail, 'mattermost', 'in-product-cloud'); }, }, }); @@ -1013,7 +1020,7 @@ class PurchaseModal extends React.PureComponent { }); }} contactSupportLink={ - this.props.contactSalesLink + this.props.contactSupportLink } currentTeam={this.props.currentTeam} onSuccess={() => { diff --git a/webapp/channels/src/components/self_hosted_purchase_modal/contact_sales_link.tsx b/webapp/channels/src/components/self_hosted_purchase_modal/contact_sales_link.tsx index 350e44cb9f..a34e11df60 100644 --- a/webapp/channels/src/components/self_hosted_purchase_modal/contact_sales_link.tsx +++ b/webapp/channels/src/components/self_hosted_purchase_modal/contact_sales_link.tsx @@ -4,18 +4,17 @@ import React from 'react'; import {useIntl} from 'react-intl'; -import {useSelector} from 'react-redux'; import {trackEvent} from 'actions/telemetry_actions'; -import {getCloudContactUsLink, InquiryType} from 'selectors/cloud'; import { TELEMETRY_CATEGORIES, } from 'utils/constants'; +import useOpenSalesLink from 'components/common/hooks/useOpenSalesLink'; import ExternalLink from 'components/external_link'; export default function ContactSalesLink() { - const contactSupportLink = useSelector(getCloudContactUsLink)(InquiryType.Technical); + const [, contactSalesLink] = useOpenSalesLink(); const intl = useIntl(); return ( {intl.formatMessage({id: 'self_hosted_signup.contact_sales', defaultMessage: 'Contact Sales'})} diff --git a/webapp/channels/src/components/self_hosted_purchase_modal/error.tsx b/webapp/channels/src/components/self_hosted_purchase_modal/error.tsx index 10da32432d..3813f9efda 100644 --- a/webapp/channels/src/components/self_hosted_purchase_modal/error.tsx +++ b/webapp/channels/src/components/self_hosted_purchase_modal/error.tsx @@ -4,13 +4,11 @@ import React from 'react'; import {FormattedMessage} from 'react-intl'; -import {useSelector} from 'react-redux'; - -import {getCloudContactUsLink, InquiryType} from 'selectors/cloud'; import PaymentFailedSvg from 'components/common/svg_images_components/payment_failed_svg'; import AccessDeniedHappySvg from 'components/common/svg_images_components/access_denied_happy_svg'; import IconMessage from 'components/purchase_modal/icon_message'; +import {useOpenSelfHostedZendeskSupportForm} from 'components/common/hooks/useOpenZendeskForm'; import ExternalLink from 'components/external_link'; interface Props { @@ -20,7 +18,7 @@ interface Props { } export default function ErrorPage(props: Props) { - const contactSupportLink = useSelector(getCloudContactUsLink)(InquiryType.Technical); + const [, contactSupportLink] = useOpenSelfHostedZendeskSupportForm('Purchase error'); let formattedTitle = ( { dispatch(getPrevTrialLicense()); @@ -54,14 +54,6 @@ function ADLDAPUpsellBanner() { const currentLicenseEndDate = new Date(parseInt(currentLicense?.ExpiresAt, 10)); - const openLink = () => { - if (isCloud) { - openSalesLink(); - } else { - window.open(LicenseLinks.CONTACT_SALES, '_blank'); - } - }; - const confirmBanner = (
@@ -71,7 +63,7 @@ function ADLDAPUpsellBanner() {
@@ -122,7 +114,7 @@ function ADLDAPUpsellBanner() { btn = ( diff --git a/webapp/channels/src/selectors/cloud.ts b/webapp/channels/src/selectors/cloud.ts index 9786b1f5e0..684a4e6c25 100644 --- a/webapp/channels/src/selectors/cloud.ts +++ b/webapp/channels/src/selectors/cloud.ts @@ -4,51 +4,10 @@ import {Invoice, Subscription} from '@mattermost/types/cloud'; import {getConfig} from 'mattermost-redux/selectors/entities/general'; -import {getCurrentUser} from 'mattermost-redux/selectors/entities/users'; import {createSelector} from 'reselect'; import {GlobalState} from 'types/store'; -export enum InquiryType { - Technical = 'technical', - Sales = 'sales', - Billing = 'billing', -} - -export enum TechnicalInquiryIssue { - AdminConsole = 'admin_console', - MattermostMessaging = 'mm_messaging', - DataExport = 'data_export', - Other = 'other', -} - -export enum SalesInquiryIssue { - AboutPurchasing = 'about_purchasing', - CancelAccount = 'cancel_account', - PurchaseNonprofit = 'purchase_nonprofit', - TrialQuestions = 'trial_questions', - UpgradeEnterprise = 'upgrade_enterprise', - SomethingElse = 'something_else', -} - -type Issue = SalesInquiryIssue | TechnicalInquiryIssue - -export const getCloudContactUsLink: (state: GlobalState) => (inquiry: InquiryType, inquiryIssue?: Issue) => string = createSelector( - 'getCloudContactUsLink', - getConfig, - getCurrentUser, - (config, user) => { - // cloud/contact-us with query params for name, email and inquiry - const cwsUrl = config.CWSURL; - const fullName = `${user.first_name} ${user.last_name}`; - return (inquiry: InquiryType, inquiryIssue?: Issue) => { - const inquiryIssueQuery = inquiryIssue ? `&inquiry-issue=${inquiryIssue}` : ''; - - return `${cwsUrl}/cloud/contact-us?email=${encodeURIComponent(user.email)}&name=${encodeURIComponent(fullName)}&inquiry=${inquiry}${inquiryIssueQuery}`; - }; - }, -); - export const getExpandSeatsLink: (state: GlobalState) => (licenseId: string) => string = createSelector( 'getExpandSeatsLink', getConfig, diff --git a/webapp/channels/src/utils/contact_support_sales.ts b/webapp/channels/src/utils/contact_support_sales.ts new file mode 100644 index 0000000000..1899d599a6 --- /dev/null +++ b/webapp/channels/src/utils/contact_support_sales.ts @@ -0,0 +1,100 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {Buffer} from 'buffer'; + +import {LicenseLinks} from './constants'; + +const baseZendeskFormURL = 'https://support.mattermost.com/hc/en-us/requests/new'; + +export enum ZendeskSupportForm { + SELF_HOSTED_SUPPORT_FORM = '11184911962004', + CLOUD_SUPPORT_FORM = '11184929555092', +} + +export enum ZendeskFormFieldIDs { + CLOUD_WORKSPACE_URL = '5245314479252', + SELF_HOSTED_ENVIRONMENT = '360026980452', + BILLING_SALES_CATEGORY = '360031056451', + EMAIL = 'anonymous_requester_email', + SUBJECT = 'subject', + DESCRIPTION = 'description' +} + +export type PrefillFieldFormFieldIDs = { + id: ZendeskFormFieldIDs; + val: string; +} + +export const buildZendeskSupportForm = (form: ZendeskSupportForm, formFieldIDs: PrefillFieldFormFieldIDs[]): string => { + let formUrl = `${baseZendeskFormURL}?ticket_form_id=${form}`; + + formFieldIDs.forEach((formPrefill) => { + formUrl = formUrl.concat(`&tf_${formPrefill.id}=${formPrefill.val}`); + }); + + if (form === ZendeskSupportForm.SELF_HOSTED_SUPPORT_FORM) { + formUrl = formUrl.concat(`&tf_${ZendeskFormFieldIDs.SELF_HOSTED_ENVIRONMENT}=production`); + } + + return formUrl; +}; + +export const goToSelfHostedSupportForm = (email: string, subject: string) => { + const form = ZendeskSupportForm.SELF_HOSTED_SUPPORT_FORM; + const url = buildZendeskSupportForm(form, [ + {id: ZendeskFormFieldIDs.EMAIL, val: email}, + {id: ZendeskFormFieldIDs.SUBJECT, val: subject}, + ]); + window.open(url, '_blank'); +}; + +export const getSelfHostedSupportLink = (email: string, subject: string) => { + const form = ZendeskSupportForm.SELF_HOSTED_SUPPORT_FORM; + const url = buildZendeskSupportForm(form, [ + {id: ZendeskFormFieldIDs.EMAIL, val: email}, + {id: ZendeskFormFieldIDs.SUBJECT, val: subject}, + ]); + return url; +}; + +export const goToCloudSupportForm = (email: string, subject: string, description: string, workspaceURL: string) => { + const form = ZendeskSupportForm.CLOUD_SUPPORT_FORM; + let url = buildZendeskSupportForm(form, [ + {id: ZendeskFormFieldIDs.EMAIL, val: email}, + {id: ZendeskFormFieldIDs.SUBJECT, val: subject}, + {id: ZendeskFormFieldIDs.DESCRIPTION, val: description}, + ]); + url = url.concat(`&tf_${ZendeskFormFieldIDs.CLOUD_WORKSPACE_URL}=${workspaceURL}`); + window.open(url, '_blank'); +}; + +export const getCloudSupportLink = (email: string, subject: string, description: string, workspaceURL: string) => { + const form = ZendeskSupportForm.CLOUD_SUPPORT_FORM; + let url = buildZendeskSupportForm(form, [ + {id: ZendeskFormFieldIDs.EMAIL, val: email}, + {id: ZendeskFormFieldIDs.SUBJECT, val: subject}, + {id: ZendeskFormFieldIDs.DESCRIPTION, val: description}, + ]); + url = url.concat(`&tf_${ZendeskFormFieldIDs.CLOUD_WORKSPACE_URL}=${workspaceURL}`); + return url; +}; + +const encodeString = (s: string) => { + return Buffer.from(s).toString('base64'); +}; + +export const buildMMURL = (baseURL: string, firstName: string, lastName: string, companyName: string, businessEmail: string, source: string, medium: string) => { + const mmURL = `${baseURL}?qk=${encodeString(firstName)}&qp=${encodeString(lastName)}&qw=${encodeString(companyName)}&qx=${encodeString(businessEmail)}&utm_source=${source}&utm_medium=${medium}`; + return mmURL; +}; + +export const goToMattermostContactSalesForm = (firstName: string, lastName: string, companyName: string, businessEmail: string, source: string, medium: string) => { + const url = buildMMURL(LicenseLinks.CONTACT_SALES, firstName, lastName, companyName, businessEmail, source, medium); + window.open(url, '_blank'); +}; + +export const getCloudContactSalesLink = (firstName: string, lastName: string, companyName: string, businessEmail: string, source: string, medium: string) => { + const url = buildMMURL(LicenseLinks.CONTACT_SALES, firstName, lastName, companyName, businessEmail, source, medium); + return url; +}; From 884e8e280a97d457ec768c8f7ca914af3276a528 Mon Sep 17 00:00:00 2001 From: Pantelis Vratsalis Date: Mon, 27 Mar 2023 12:42:55 +0200 Subject: [PATCH 15/46] Translated using Weblate (Spanish) Currently translated at 93.6% (2384 of 2546 strings) Translation: mattermost-languages-shipped/mattermost-server-monorepo Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server-monorepo/es/ --- server/i18n/es.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server/i18n/es.json b/server/i18n/es.json index 891462edb8..0e1791f125 100644 --- a/server/i18n/es.json +++ b/server/i18n/es.json @@ -9546,5 +9546,9 @@ { "id": "api.admin.syncables_error", "translation": "Error al agregar usuario a grupo-equipos y grupo-canales" + }, + { + "id": "api.command_templates.name", + "translation": "plantillas" } ] From d6dab948473e5d04f8370d6c71d6aff1c1d7747e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Vay=C3=A1?= Date: Mon, 27 Mar 2023 12:42:56 +0200 Subject: [PATCH 16/46] Translated using Weblate (Spanish) Currently translated at 89.4% (5152 of 5758 strings) Translation: mattermost-languages-shipped/mattermost-webapp-monorepo Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp-monorepo/es/ Translated using Weblate (Spanish) Currently translated at 89.4% (5152 of 5758 strings) Translation: mattermost-languages-shipped/mattermost-webapp-monorepo Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp-monorepo/es/ --- webapp/channels/src/i18n/es.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/webapp/channels/src/i18n/es.json b/webapp/channels/src/i18n/es.json index 4e349c4a1c..28de93f5e2 100644 --- a/webapp/channels/src/i18n/es.json +++ b/webapp/channels/src/i18n/es.json @@ -255,6 +255,7 @@ "admin.billing.company_info_edit.sameAsBillingAddress": "Igual que la dirección de facturación", "admin.billing.company_info_edit.save": "Guardar información", "admin.billing.company_info_edit.title": "Editar información de la empresa", + "admin.billing.deleteWorkspace.failureModal.buttonText": "Prueba de nuevo", "admin.billing.history.allPaymentsShowHere": "Todos sus pagos mensuales se mostrarán aquí", "admin.billing.history.date": "Fecha", "admin.billing.history.description": "Descripción", @@ -3898,9 +3899,6 @@ "modal.manual_status.title_ooo": "Tu estado actual es \"Fuera de Oficina\"", "more.details": "Más detalles", "more_channels.create": "Crear Canal", - "more_channels.createClick": "Haz clic en 'Crear Nuevo Canal' para crear uno nuevo", - "more_channels.join": "Unirse", - "more_channels.joining": "Uniendo...", "more_channels.next": "Siguiente", "more_channels.noMore": "No hay más canales para unirse", "more_channels.prev": "Anterior", From 1a01dedfeebe712fac9d8b68d6224d103059bcc1 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Mon, 27 Mar 2023 12:42:57 +0200 Subject: [PATCH 17/46] Update translation files Updated by "Cleanup translation files" hook in Weblate. Translation: mattermost-languages-shipped/mattermost-webapp-monorepo Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp-monorepo/ Update translation files Updated by "Cleanup translation files" hook in Weblate. Translation: mattermost-languages-shipped/mattermost-webapp-monorepo Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp-monorepo/ --- webapp/channels/src/i18n/bg.json | 2 -- webapp/channels/src/i18n/de.json | 3 --- webapp/channels/src/i18n/en_AU.json | 3 --- webapp/channels/src/i18n/fa.json | 3 --- webapp/channels/src/i18n/fr.json | 3 --- webapp/channels/src/i18n/hu.json | 3 --- webapp/channels/src/i18n/it.json | 2 -- webapp/channels/src/i18n/ja.json | 3 --- webapp/channels/src/i18n/ko.json | 2 -- webapp/channels/src/i18n/nl.json | 3 --- webapp/channels/src/i18n/pl.json | 3 --- webapp/channels/src/i18n/pt-BR.json | 2 -- webapp/channels/src/i18n/ro.json | 2 -- webapp/channels/src/i18n/ru.json | 3 --- webapp/channels/src/i18n/sv.json | 3 --- webapp/channels/src/i18n/tr.json | 3 --- webapp/channels/src/i18n/uk.json | 1 - webapp/channels/src/i18n/zh-CN.json | 3 --- webapp/channels/src/i18n/zh-TW.json | 2 -- 19 files changed, 49 deletions(-) diff --git a/webapp/channels/src/i18n/bg.json b/webapp/channels/src/i18n/bg.json index ac169a02b8..c5331d8e9c 100644 --- a/webapp/channels/src/i18n/bg.json +++ b/webapp/channels/src/i18n/bg.json @@ -3484,8 +3484,6 @@ "modal.manual_status.title_offline": "Вашето състояние е зададено на \"Извън линия\"", "modal.manual_status.title_ooo": "Вашето състояние е зададено на \"Извън офиса\"", "more_channels.create": "Създайте канал", - "more_channels.createClick": "Кликнете върху \"Създаване на нов канал\", за да създадете канал", - "more_channels.joining": "Присъединявне ...", "more_channels.next": "Следващ", "more_channels.noMore": "Няма повече канали за присъединяване", "more_channels.prev": "Предишен", diff --git a/webapp/channels/src/i18n/de.json b/webapp/channels/src/i18n/de.json index 91cf9e29ab..a9ab534958 100644 --- a/webapp/channels/src/i18n/de.json +++ b/webapp/channels/src/i18n/de.json @@ -4157,9 +4157,6 @@ "modal.manual_status.title_ooo": "Dein Status ist auf \"Nicht im Büro\" gesetzt", "more.details": "Mehr Details", "more_channels.create": "Kanal erstellen", - "more_channels.createClick": "Klicke auf 'Neuen Kanal erstellen' um einen Neuen zu erzeugen", - "more_channels.join": "Beitreten", - "more_channels.joining": "Betrete...", "more_channels.next": "Weiter", "more_channels.noMore": "Keine weiteren Kanäle, denen beigetreten werden kann", "more_channels.prev": "Zurück", diff --git a/webapp/channels/src/i18n/en_AU.json b/webapp/channels/src/i18n/en_AU.json index a1efa880c5..a8a38f34e8 100644 --- a/webapp/channels/src/i18n/en_AU.json +++ b/webapp/channels/src/i18n/en_AU.json @@ -4153,9 +4153,6 @@ "modal.manual_status.title_ooo": "Your Status is Set to 'Out of Office'", "more.details": "More details", "more_channels.create": "Create Channel", - "more_channels.createClick": "Click 'Create New Channel' to make a new one", - "more_channels.join": "Join", - "more_channels.joining": "Joining...", "more_channels.next": "Next", "more_channels.noMore": "No more channels to join", "more_channels.prev": "Previous", diff --git a/webapp/channels/src/i18n/fa.json b/webapp/channels/src/i18n/fa.json index ade499d8b7..90132c93a1 100644 --- a/webapp/channels/src/i18n/fa.json +++ b/webapp/channels/src/i18n/fa.json @@ -3707,9 +3707,6 @@ "modal.manual_status.title_ooo": "وضعیت شما روی \"خارج از دفتر\" تنظیم شده است", "more.details": "جزئیات بیشتر", "more_channels.create": "ایجاد کانال", - "more_channels.createClick": "برای ایجاد کانال جدید روی \"ایجاد کانال جدید\" کلیک کنید", - "more_channels.join": "پیوستن", - "more_channels.joining": "پیوستن...", "more_channels.next": "بعد", "more_channels.noMore": "کانال دیگری برای پیوستن وجود ندارد", "more_channels.prev": "قبلی", diff --git a/webapp/channels/src/i18n/fr.json b/webapp/channels/src/i18n/fr.json index 64a3dcf932..0b4cc9471e 100644 --- a/webapp/channels/src/i18n/fr.json +++ b/webapp/channels/src/i18n/fr.json @@ -3736,9 +3736,6 @@ "modal.manual_status.title_offline": "Votre statut est défini sur « Hors ligne »", "modal.manual_status.title_ooo": "Votre statut est défini sur « Absent du bureau »", "more_channels.create": "Créer un canal", - "more_channels.createClick": "Veuillez cliquer sur « Créer un nouveau canal » pour en créer un nouveau", - "more_channels.join": "Rejoindre", - "more_channels.joining": "Accès en cours...", "more_channels.next": "Suivant", "more_channels.noMore": "Il n'y a plus d'autre canal que vous pouvez rejoindre", "more_channels.prev": "Précédent", diff --git a/webapp/channels/src/i18n/hu.json b/webapp/channels/src/i18n/hu.json index 5eef371fe0..cf69f79c4c 100644 --- a/webapp/channels/src/i18n/hu.json +++ b/webapp/channels/src/i18n/hu.json @@ -3920,9 +3920,6 @@ "modal.manual_status.title_ooo": "Az Ön állapota \"Irodán kívül\" -re van állítva", "more.details": "További információ", "more_channels.create": "Csatorna létrehozása", - "more_channels.createClick": "Kattintson az \"Új csatorna létrehozása\" gombra egy új létrehozásához", - "more_channels.join": "Csatlakozás", - "more_channels.joining": "Csatlakozás...", "more_channels.next": "Következő", "more_channels.noMore": "Nincs több beszélgetés amelyhez csatlakozni lehetne", "more_channels.prev": "Előző", diff --git a/webapp/channels/src/i18n/it.json b/webapp/channels/src/i18n/it.json index 475ca8ab90..b64ecd9cd4 100644 --- a/webapp/channels/src/i18n/it.json +++ b/webapp/channels/src/i18n/it.json @@ -2997,8 +2997,6 @@ "modal.manual_status.title_offline": "Il tuo stato è \"Non in linea\"", "modal.manual_status.title_ooo": "Il tuo stato è \"Fuori sede\"", "more_channels.create": "Crea canale", - "more_channels.createClick": "Click 'Crea un nuovo canale' per crearne uno nuovo", - "more_channels.joining": "Accoppiamento...", "more_channels.next": "Prossimo", "more_channels.noMore": "Nessun altro canale in cui entrare", "more_channels.prev": "Precedente", diff --git a/webapp/channels/src/i18n/ja.json b/webapp/channels/src/i18n/ja.json index 6a60d919b3..01d621261e 100644 --- a/webapp/channels/src/i18n/ja.json +++ b/webapp/channels/src/i18n/ja.json @@ -4155,9 +4155,6 @@ "modal.manual_status.title_ooo": "ステータスが \"外出中\" になりました", "more.details": "もっと詳しく", "more_channels.create": "チャンネルを作成する", - "more_channels.createClick": "新しいチャンネルを作成するには「チャンネルを作成する」をクリックしてください", - "more_channels.join": "参加", - "more_channels.joining": "参加しています....", "more_channels.next": "次へ", "more_channels.noMore": "参加できるチャンネルがありません", "more_channels.prev": "前へ", diff --git a/webapp/channels/src/i18n/ko.json b/webapp/channels/src/i18n/ko.json index 9f36cadb38..a73022b548 100644 --- a/webapp/channels/src/i18n/ko.json +++ b/webapp/channels/src/i18n/ko.json @@ -2883,8 +2883,6 @@ "modal.manual_status.title_offline": "상태가 \"오프라인\"이 되셨습니다", "modal.manual_status.title_ooo": "상태가 \"오프라인\"이 되셨습니다", "more_channels.create": "채널 만들기", - "more_channels.createClick": "'새로 만들기'를 클릭하여 새로운 채널을 만드세요", - "more_channels.joining": "참가 중...", "more_channels.next": "다음", "more_channels.noMore": "가입할 수 있는 채널이 없습니다", "more_channels.prev": "이전", diff --git a/webapp/channels/src/i18n/nl.json b/webapp/channels/src/i18n/nl.json index d9b49b646b..2b0c2deccf 100644 --- a/webapp/channels/src/i18n/nl.json +++ b/webapp/channels/src/i18n/nl.json @@ -4155,9 +4155,6 @@ "modal.manual_status.title_ooo": "Je status is ingesteld op \"Out of Office\"", "more.details": "Meer details", "more_channels.create": "Kanaal aanmaken", - "more_channels.createClick": "Klik 'Maak nieuw kanaal' om een nieuw kanaal te maken", - "more_channels.join": "Deelnemen", - "more_channels.joining": "Lid worden...", "more_channels.next": "Volgende", "more_channels.noMore": "Geen kanalen beschikbaar waar aan deelgenomen kan worden", "more_channels.prev": "Vorige", diff --git a/webapp/channels/src/i18n/pl.json b/webapp/channels/src/i18n/pl.json index 3ce35e3fed..7786f19479 100644 --- a/webapp/channels/src/i18n/pl.json +++ b/webapp/channels/src/i18n/pl.json @@ -4157,9 +4157,6 @@ "modal.manual_status.title_ooo": "Twój status został ustawiony na \"Poza biurem\"", "more.details": "Więcej informacji", "more_channels.create": "Stwórz kanał", - "more_channels.createClick": "Kliknij przycisk 'Utwórz nowy kanał', aby dodać nowy", - "more_channels.join": "Dołącz do", - "more_channels.joining": "Dołączanie...", "more_channels.next": "Dalej", "more_channels.noMore": "Brak kanałów", "more_channels.prev": "Wstecz", diff --git a/webapp/channels/src/i18n/pt-BR.json b/webapp/channels/src/i18n/pt-BR.json index 43c012f677..7c727fa2d3 100644 --- a/webapp/channels/src/i18n/pt-BR.json +++ b/webapp/channels/src/i18n/pt-BR.json @@ -3216,8 +3216,6 @@ "modal.manual_status.title_offline": "Seu Status está configurado para \"Desconectado\"", "modal.manual_status.title_ooo": "Seu Status está configurado para \"Fora do Escritório\"", "more_channels.create": "Criar Canal", - "more_channels.createClick": "Clique em 'Criar Novo Canal' para fazer um novo", - "more_channels.joining": "Juntando...", "more_channels.next": "Próximo", "more_channels.noMore": "Não há mais canais para participar", "more_channels.prev": "Anterior", diff --git a/webapp/channels/src/i18n/ro.json b/webapp/channels/src/i18n/ro.json index 9d643ffde9..1f71d191a4 100644 --- a/webapp/channels/src/i18n/ro.json +++ b/webapp/channels/src/i18n/ro.json @@ -3306,8 +3306,6 @@ "modal.manual_status.title_offline": "Starea dvs. este setată la \"Offline\"", "modal.manual_status.title_ooo": "Starea dvs. este setată la \"Plecat din birou\"", "more_channels.create": "Creați un nou canal", - "more_channels.createClick": "Dați clic pe \"Creați un nou canal\" pentru a crea unul nou", - "more_channels.joining": "Aderarea...", "more_channels.next": "Următor", "more_channels.noMore": "Nu mai există canale care să se alăture", "more_channels.prev": "Anterior", diff --git a/webapp/channels/src/i18n/ru.json b/webapp/channels/src/i18n/ru.json index f5260c57cf..bfca5442bf 100644 --- a/webapp/channels/src/i18n/ru.json +++ b/webapp/channels/src/i18n/ru.json @@ -4157,9 +4157,6 @@ "modal.manual_status.title_ooo": "Ваш статус установлен на \"Не на работе\"", "more.details": "Подробнее", "more_channels.create": "Создать канал", - "more_channels.createClick": "Нажмите 'Создать канал' для создания нового канала", - "more_channels.join": "Присоединиться", - "more_channels.joining": "Присоединяемся...", "more_channels.next": "Далее", "more_channels.noMore": "Доступных каналов не найдено", "more_channels.prev": "Предыдущая", diff --git a/webapp/channels/src/i18n/sv.json b/webapp/channels/src/i18n/sv.json index f9280f8c21..9ed2615d87 100644 --- a/webapp/channels/src/i18n/sv.json +++ b/webapp/channels/src/i18n/sv.json @@ -4157,9 +4157,6 @@ "modal.manual_status.title_ooo": "Din status är satt till \"Inte på kontoret\"", "more.details": "Mer information", "more_channels.create": "Skapa kanal", - "more_channels.createClick": "Tryck 'Skapa ny kanal' för att skapa en ny", - "more_channels.join": "Gå med", - "more_channels.joining": "Ansluter...", "more_channels.next": "Nästa", "more_channels.noMore": "Det finns inga fler kanaler att gå med i", "more_channels.prev": "Föregående", diff --git a/webapp/channels/src/i18n/tr.json b/webapp/channels/src/i18n/tr.json index 91700905d0..4c4e6c1fed 100644 --- a/webapp/channels/src/i18n/tr.json +++ b/webapp/channels/src/i18n/tr.json @@ -4093,9 +4093,6 @@ "modal.manual_status.title_ooo": "Durumunuz \"Ofis dışında\" olarak değiştirildi", "more.details": "Ayrıntılı bilgi", "more_channels.create": "Kanal ekle", - "more_channels.createClick": "Yeni bir kanal eklemek için 'Yeni kanal ekle' üzerine tıklayın", - "more_channels.join": "Katıl", - "more_channels.joining": "Katılınıyor...", "more_channels.next": "Sonraki", "more_channels.noMore": "Katılabileceğiniz başka bir kanal yok", "more_channels.prev": "Önceki", diff --git a/webapp/channels/src/i18n/uk.json b/webapp/channels/src/i18n/uk.json index be24267d9c..4afba9192e 100644 --- a/webapp/channels/src/i18n/uk.json +++ b/webapp/channels/src/i18n/uk.json @@ -2246,7 +2246,6 @@ "modal.manual_status.title_offline": "Ваш статус встановлено на \"Offline\"", "modal.manual_status.title_ooo": "Ваш статус встановлено на \"За межами офісу\"", "more_channels.create": "Створити канал", - "more_channels.createClick": "Натисніть 'Створити новий канал' для створення нового каналу", "more_channels.next": "Далі", "more_channels.noMore": "Більше немає каналів для входу", "more_channels.prev": "Попередній", diff --git a/webapp/channels/src/i18n/zh-CN.json b/webapp/channels/src/i18n/zh-CN.json index f7dc1ff425..34642cf7a3 100644 --- a/webapp/channels/src/i18n/zh-CN.json +++ b/webapp/channels/src/i18n/zh-CN.json @@ -3581,9 +3581,6 @@ "modal.manual_status.title_offline": "您的状态已设置为 \"离线\"", "modal.manual_status.title_ooo": "您的状态已设置为 \"离开办公室\"", "more_channels.create": "创建频道", - "more_channels.createClick": "点击'创建新频道'创建一个新的频道", - "more_channels.join": "加入", - "more_channels.joining": "加入中...", "more_channels.next": "下一页", "more_channels.noMore": "没有更多可加入的频道", "more_channels.prev": "上一页", diff --git a/webapp/channels/src/i18n/zh-TW.json b/webapp/channels/src/i18n/zh-TW.json index 67076d9959..63c968580a 100644 --- a/webapp/channels/src/i18n/zh-TW.json +++ b/webapp/channels/src/i18n/zh-TW.json @@ -2913,8 +2913,6 @@ "modal.manual_status.title_offline": "狀態已設為\"離線\"", "modal.manual_status.title_ooo": "狀態已設為\"不在辦公室\"", "more_channels.create": "建立頻道", - "more_channels.createClick": "按下'建立頻道'來建立新頻道", - "more_channels.joining": "加入中...", "more_channels.next": "下一頁", "more_channels.noMore": "沒有可參加的頻道", "more_channels.prev": "上一頁", From ecf800edc11183559a509f022c9c68f120bf608d Mon Sep 17 00:00:00 2001 From: Frank Tang Date: Mon, 27 Mar 2023 12:42:57 +0200 Subject: [PATCH 18/46] Translated using Weblate (Chinese (Simplified)) Currently translated at 79.6% (4587 of 5759 strings) Translation: mattermost-languages-shipped/mattermost-webapp-monorepo Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp-monorepo/zh_Hans/ Translated using Weblate (Chinese (Simplified)) Currently translated at 79.5% (4583 of 5758 strings) Translation: mattermost-languages-shipped/mattermost-webapp-monorepo Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp-monorepo/zh_Hans/ Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (2546 of 2546 strings) Translation: mattermost-languages-shipped/mattermost-server-monorepo Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server-monorepo/zh_Hans/ --- server/i18n/zh-CN.json | 348 ++++++++++++++++++++++++++++ webapp/channels/src/i18n/zh-CN.json | 17 +- 2 files changed, 363 insertions(+), 2 deletions(-) diff --git a/server/i18n/zh-CN.json b/server/i18n/zh-CN.json index 143659ad85..3cc21656bd 100644 --- a/server/i18n/zh-CN.json +++ b/server/i18n/zh-CN.json @@ -9858,5 +9858,353 @@ { "id": "api.command_templates.unsupported.app_error", "translation": "您的设备不支持模板命令。" + }, + { + "id": "worktemplate.product_teams.sprint_planning.integration", + "translation": "项目面板可以使迭代计划前所未来的容易。频道可以用来对话和保证问题的被关注。迭代计划面板可以使所以有本周对任务的关注,回顾面板让团队作为一个整体不断改进。" + }, + { + "id": "worktemplate.product_teams.sprint_planning.channel", + "translation": "项目面板可以使迭代计划前所未来的容易。频道可以用来对话和保证问题的被关注。迭代计划面板可以使所以有本周对任务的关注,回顾面板让团队作为一个整体不断改进。" + }, + { + "id": "worktemplate.product_teams.sprint_planning.board", + "translation": "项目面板可以使迭代计划前所未来的容易。频道可以用来对话和保证问题的被关注。迭代计划面板可以使所以有本周对任务的关注,回顾面板让团队作为一个整体不断改进。" + }, + { + "id": "worktemplate.product_teams.product_roadmap.channel", + "translation": "这里描述了为什么需要面板" + }, + { + "id": "worktemplate.product_teams.product_roadmap.board", + "translation": "这里描述了为什么需要面板" + }, + { + "id": "worktemplate.product_teams.goals_and_okrs.integration", + "translation": "清晰的目标对团队的成功至关重要,在此项目里你可以在文档里写下团队的目标和OKR,并在相关的频道里会有消息提醒。" + }, + { + "id": "worktemplate.product_teams.goals_and_okrs.channel", + "translation": "清晰的目标对团队的成功至关重要,在此项目里你可以在文档里写下团队的目标和OKR,并在相关的频道里会有消息提醒。" + }, + { + "id": "worktemplate.product_teams.goals_and_okrs.board", + "translation": "清晰的目标对团队的成功至关重要,在此项目里你可以在文档里写下团队的目标和OKR,并在相关的频道里会有消息提醒。" + }, + { + "id": "worktemplate.product_teams.feature_release.description.playbook", + "translation": "通过建立透明的跨越整个研发团队的工作流程确保你的功能开发过程完美流畅。" + }, + { + "id": "worktemplate.product_teams.feature_release.description.integration", + "translation": "在你的频道通过集成Jira和Gtihub机器人提高效率。这些会自动下载安装。" + }, + { + "id": "worktemplate.product_teams.feature_release.description.channel", + "translation": "Boards,Playbooks和应用Bot可以很容易地接入功能发布频道并且和你的团队进行相关互动和讨论。" + }, + { + "id": "worktemplate.product_teams.feature_release.description.board", + "translation": "使用我们的会议日程模板安排像站立会议这样的定期会议,使用我们的项目任务面板在一路上管理任务的进度。" + }, + { + "id": "worktemplate.product_teams.bug_bash.playbook", + "translation": "把事情安排好并且干掉此项目里的所有bug!用包含的Playbook, Board, and Channel推动项目并评估进度。" + }, + { + "id": "worktemplate.product_teams.bug_bash.integration", + "translation": "把事情安排好并且干掉此项目里的所有bug!用包含的Playbook, Board, and Channel推动项目并评估进度。" + }, + { + "id": "worktemplate.product_teams.bug_bash.channel", + "translation": "把事情安排好并且干掉此项目里的所有bug!用包含的Playbook, Board, and Channel推动项目并评估进度。" + }, + { + "id": "worktemplate.product_teams.bug_bash.board", + "translation": "把事情安排好并且干掉此项目里的所有bug!用包含的Playbook, Board, and Channel推动项目并评估进度。" + }, + { + "id": "worktemplate.leadership.goals_and_okrs.integration", + "translation": "清晰的目标对团队的成功至关重要,在此项目里你可以在文档里写下团队的目标和OKR,并在相关的频道里会有消息提醒。" + }, + { + "id": "worktemplate.leadership.goals_and_okrs.channel", + "translation": "清晰的目标对团队的成功至关重要,在此项目里你可以在文档里写下团队的目标和OKR,并在相关的频道里会有消息提醒。" + }, + { + "id": "worktemplate.leadership.goals_and_okrs.board", + "translation": "清晰的目标对团队的成功至关重要,在此项目里你可以在文档里写下团队的目标和OKR,并在相关的频道里会有消息提醒。" + }, + { + "id": "worktemplate.devops.product_release.playbook", + "translation": "不要丢失此项目的任何一个步骤。从Playbook的检验清单分离成任务部署并达到项目面板的里程碑。用频道来保持所有人对事情的理解一致。" + }, + { + "id": "worktemplate.devops.product_release.channel", + "translation": "不要丢失此项目的任何一个步骤。从Playbook的检验清单分离成任务部署并达到项目面板的里程碑。用频道来保持所有人对事情的理解一致。" + }, + { + "id": "worktemplate.devops.product_release.board", + "translation": "不要丢失此项目的任何一个步骤。从Playbook的检验清单分离成任务部署并达到项目面板的里程碑。用频道来保持所有人对事情的理解一致。" + }, + { + "id": "worktemplate.devops.incident_resolution.description.playbook", + "translation": "当到处都是问题的时候,有一个能够确保一切都尽快回归正确的可重复流程是关键。此项目使用Mattermost提供的一切功能保证火被一步步扑灭以及利益相关者被告知。" + }, + { + "id": "worktemplate.devops.incident_resolution.description.channel", + "translation": "当到处都是问题的时候,有一个能够确保一切都尽快回归正确的可重复流程是关键。此项目使用Mattermost提供的一切功能保证火被一步步扑灭以及利益相关者被告知。" + }, + { + "id": "worktemplate.devops.incident_resolution.description.board", + "translation": "当到处都是问题的时候,有一个能够确保一切都尽快回归正确的可重复流程是关键。此项目使用Mattermost提供的一切功能保证火被一步步扑灭以及利益相关者被告知。" + }, + { + "id": "worktemplate.companywide.goals_and_okrs.integration", + "translation": "清晰的目标对团队的成功至关重要,在此项目里你可以在文档里写下团队的目标和OKR,并在相关的频道里会有消息提醒。" + }, + { + "id": "worktemplate.companywide.goals_and_okrs.channel", + "translation": "清晰的目标对团队的成功至关重要,在此项目里你可以在文档里写下团队的目标和OKR,并在相关的频道里会有消息提醒。" + }, + { + "id": "worktemplate.companywide.goals_and_okrs.board", + "translation": "清晰的目标对团队的成功至关重要,在此项目里你可以在文档里写下团队的目标和OKR,并在相关的频道里会有消息提醒。" + }, + { + "id": "worktemplate.companywide.create_project.integration", + "translation": "使用此项目面板设计一个路线图,并在产生的频道里就相应话题进行探讨合作。" + }, + { + "id": "worktemplate.companywide.create_project.channel", + "translation": "使用此项目面板设计一个路线图,并在产生的频道里就相应话题进行探讨合作。" + }, + { + "id": "worktemplate.companywide.create_project.board", + "translation": "使用此项目面板设计一个路线图,并在产生的频道里就相应话题进行探讨合作。" + }, + { + "id": "app.user.run.update_status.title", + "translation": "状态更新" + }, + { + "id": "app.user.run.update_status.submit_label", + "translation": "更新状态" + }, + { + "id": "app.user.run.update_status.reminder_for_next_update", + "translation": "下次更新的提醒" + }, + { + "id": "app.user.run.update_status.num_channel", + "translation": { + "other": "为利益相关者提供一次更新提醒。这条提醒将被广播到{{.Count}} 个频道。" + } + }, + { + "id": "app.user.run.update_status.finish_run.placeholder", + "translation": "并且标记此运行为已结束" + }, + { + "id": "app.user.run.update_status.finish_run", + "translation": "结束运行" + }, + { + "id": "app.user.run.update_status.change_since_last_update", + "translation": "对比上次存在更改" + }, + { + "id": "app.user.run.status_enable", + "translation": "@{{.Username}} 启用了对 [{{.RunName}}]({{.RunURL}})的状态更新" + }, + { + "id": "app.user.run.status_disable", + "translation": "@{{.Username}} 停止用了 [{{.RunName}}]({{.RunURL}})的状态更新。" + }, + { + "id": "app.user.run.request_update", + "translation": "@here — @{{.Name}} 请求对 [{{.RunName}}]({{.RunURL}}) 进行状态更新。 \n" + }, + { + "id": "app.user.run.request_join_channel", + "translation": "@{{.Name}} 是一个运行的参与者,并且希望要参加这个频道。任何的频道成员都可以邀请他们。\n" + }, + { + "id": "app.user.run.confirm_finish.title", + "translation": "确认完成运行" + }, + { + "id": "app.user.run.confirm_finish.submit_label", + "translation": "完成运行" + }, + { + "id": "app.user.run.confirm_finish.num_outstanding", + "translation": { + "other": "一共有 **{{.Count}} 未完成的任务**. 您确定想为所有的参与者结束*{{.RunName}}*吗?" + } + }, + { + "id": "app.user.run.add_to_timeline.title", + "translation": "添加到运行队列" + }, + { + "id": "app.user.run.add_to_timeline.summary.placeholder", + "translation": "时间表里显示的简单概要" + }, + { + "id": "app.user.run.add_to_timeline.summary.help", + "translation": "最大64个字符" + }, + { + "id": "app.user.run.add_to_timeline.summary", + "translation": "概要" + }, + { + "id": "app.user.run.add_to_timeline.submit_label", + "translation": "添加到运行队列" + }, + { + "id": "app.user.run.add_to_timeline.playbook_run", + "translation": "Playbook运行" + }, + { + "id": "app.user.run.add_checklist_item.title", + "translation": "添加新任务" + }, + { + "id": "app.user.run.add_checklist_item.submit_label", + "translation": "添加任务" + }, + { + "id": "app.user.run.add_checklist_item.name", + "translation": "名字" + }, + { + "id": "app.user.run.add_checklist_item.description", + "translation": "描述" + }, + { + "id": "app.user.new_run.title", + "translation": "运行playbook" + }, + { + "id": "app.user.new_run.submit_label", + "translation": "开始运行" + }, + { + "id": "app.user.new_run.run_name", + "translation": "运行名" + }, + { + "id": "app.user.new_run.playbook", + "translation": "Playbook" + }, + { + "id": "app.user.new_run.intro", + "translation": "**所有者** {{.Username}}" + }, + { + "id": "app.user.digest.tasks.zero_assigned", + "translation": "您没有任务。" + }, + { + "id": "app.user.digest.tasks.num_assigned_due_until_today", + "translation": { + "other": "您有 {{.Count}} 个任务现在已经逾期:" + } + }, + { + "id": "app.user.digest.tasks.num_assigned", + "translation": { + "other": "您一共有{{.Count}}个任务:" + } + }, + { + "id": "app.user.digest.tasks.heading", + "translation": "您的任务" + }, + { + "id": "app.user.digest.tasks.due_yesterday", + "translation": "于昨天过期" + }, + { + "id": "app.user.digest.tasks.due_x_days_ago", + "translation": "{{.Count}}天已过期" + }, + { + "id": "app.user.digest.tasks.due_today", + "translation": "将于今天过期" + }, + { + "id": "app.user.digest.tasks.due_in_x_days", + "translation": { + "other": "{{.Count}}天后过期" + } + }, + { + "id": "app.user.digest.tasks.due_after_today", + "translation": { + "other": "您有 **{{.Count}} 项目任务今天之后将要过期**." + } + }, + { + "id": "app.user.digest.tasks.all_tasks_command", + "translation": "请使用`/playbook todo`来查看您所有的任务。" + }, + { + "id": "app.user.digest.runs_in_progress.zero_in_progress", + "translation": "您有0项正在运行。" + }, + { + "id": "app.user.digest.runs_in_progress.num_in_progress", + "translation": { + "other": "您有{{.Count}}正在运行:" + } + }, + { + "id": "app.user.digest.runs_in_progress.heading", + "translation": "正在运行" + }, + { + "id": "app.user.digest.overdue_status_updates.zero_overdue", + "translation": "您没有逾期。" + }, + { + "id": "app.user.digest.overdue_status_updates.num_overdue", + "translation": { + "other": "您有 {{.Count}} 过期需要状态更新:" + } + }, + { + "id": "app.user.digest.overdue_status_updates.heading", + "translation": "过期状态更新" + }, + { + "id": "app.oauth.remove_auth_data_by_client_id.app_error", + "translation": "不能删除oauth认证信息。" + }, + { + "id": "app.command.execute.error", + "translation": "无法执行命令。" + }, + { + "id": "api.templates.license_up_for_renewal_contact_sales", + "translation": "联系销售" + }, + { + "id": "api.license.true_up_review.not_allowed_for_cloud", + "translation": "云实例不允许真实性评估" + }, + { + "id": "api.license.true_up_review.license_required", + "translation": "真实性评估需要许可证" + }, + { + "id": "api.license.true_up_review.get_status_error", + "translation": "无法获取真实的状态记录" + }, + { + "id": "api.license.true_up_review.create_error", + "translation": "无法创建真实的状态记录" } ] diff --git a/webapp/channels/src/i18n/zh-CN.json b/webapp/channels/src/i18n/zh-CN.json index 34642cf7a3..2db89a3255 100644 --- a/webapp/channels/src/i18n/zh-CN.json +++ b/webapp/channels/src/i18n/zh-CN.json @@ -54,6 +54,7 @@ "accessibility.sidebar.types.unread": "未读", "activityAndInsights.sidebarLink": "见解", "activityAndInsights.title": "活动与见解 - {displayName} {siteName}", + "activityAndInsights.tutorialTip.description": "查看新加入工作区的洞见功能。了解最热的内容,了解你和你的队友在怎么样使用你的工作区间。", "activityAndInsights.tutorialTip.title": "介绍:见解", "activityAndInsights.tutorial_tip.notNow": "现在不要", "activityAndInsights.tutorial_tip.viewInsights": "查看见解", @@ -255,6 +256,12 @@ "admin.billing.company_info_edit.save": "保存信息", "admin.billing.company_info_edit.title": "编辑公司信息", "admin.billing.deleteWorkspace.failureModal.buttonText": "重试", + "admin.billing.deleteWorkspace.failureModal.subtitle": "我们在删除你的工作空间时遇到了问题。请再试一次或联系技术支持。", + "admin.billing.deleteWorkspace.failureModal.title": "工作区删除失败", + "admin.billing.deleteWorkspace.progressModal.title": "删除你的工作区", + "admin.billing.deleteWorkspace.resultModal.ContactSupport": "联系客服", + "admin.billing.deleteWorkspace.successModal.subtitle": "您的工作区现在已被删除。谢谢您的惠顾。", + "admin.billing.deleteWorkspace.successModal.title": "您的工作区已被删除", "admin.billing.history.allPaymentsShowHere": "您所有的发票都将显示在这里", "admin.billing.history.date": "日期", "admin.billing.history.description": "描述", @@ -293,6 +300,7 @@ "admin.billing.purchaseModal.savedPaymentDetailsTitle": "您保存的付款详情", "admin.billing.subscription.LearnMore": "了解更多", "admin.billing.subscription.billedFrom": "您将从 {beginDate} 开始计费", + "admin.billing.subscription.byClickingYouAgree": "点击{buttonContent} ,您将同意{legalText}", "admin.billing.subscription.cancelSubscriptionSection.contactUs": "联系我们", "admin.billing.subscription.cancelSubscriptionSection.description": "目前,只能在客户支持代表的帮助下删除工作空间。", "admin.billing.subscription.cancelSubscriptionSection.title": "取消订阅", @@ -303,10 +311,15 @@ "admin.billing.subscription.cloudTrial.subscribeButton": "立刻升级", "admin.billing.subscription.cloudTrialBadge.daysLeftOnTrial": "试用期还剩 {daysLeftOnTrial} 天", "admin.billing.subscription.cloudYearlyBadge": "年度", + "admin.billing.subscription.complianceScreenFailed.button": "继续使用云免费版", + "admin.billing.subscription.complianceScreenFailed.subtitle": "一旦您的云订阅升级被批准,我们将检查相关事宜,并在3天内回复您。在此期间,请继续使用免费版本。", + "admin.billing.subscription.complianceScreenFailed.title": "您的交易正在审核中", + "admin.billing.subscription.complianceScreenShippingSameAsBilling": "我的送货地址和我的账单地址是一样的", "admin.billing.subscription.constCloudCard.contactSupport": "联系支持", "admin.billing.subscription.creditCardExpired": "您的信用卡已过期。请更新您的付款信息,以免造成任何中断。", "admin.billing.subscription.creditCardHasExpired": "您的信用卡已过期", "admin.billing.subscription.creditCardHasExpired.description": "请更新您的 付款信息 以避免任何中断服务。", + "admin.billing.subscription.deleteWorkspaceModal.usageDetails": "{messageCount} 条消息和 {fileSize} 的文件", "admin.billing.subscription.downgradedSuccess": "您现在订阅了 {productName}", "admin.billing.subscription.downgrading": "降级您的工作区", "admin.billing.subscription.featuresAvailable": "{productName} 功能现在已可以使用。", @@ -2963,7 +2976,7 @@ "emoji_picker.header": "表情选择器", "emoji_picker.objects": "物品", "emoji_picker.people-body": "人与身体", - "emoji_picker.recent": "最近使用", + "emoji_picker.recent": "最近使用过", "emoji_picker.search": "搜索表情符", "emoji_picker.searchResults": "搜索结果", "emoji_picker.search_emoji": "搜索表情符", @@ -3383,7 +3396,7 @@ "integrations.successful": "设置成功", "interactive_dialog.cancel": "取消", "interactive_dialog.element.optional": "(可选)", - "interactive_dialog.submit": "提交", + "interactive_dialog.submit": "发送", "interactive_dialog.submitting": "提交中...", "intro_messages.DM": "这是您和{teammate}私信记录的开端。\n此区域外的人不能看到这里共享的私信和文件。", "intro_messages.GM": "这是您和{names}团体消息的起端。\n此区域外的人不能看到这里共享的消息和文件。", From a6f5f0619c858e37eec43bc2b74ed890cc562991 Mon Sep 17 00:00:00 2001 From: kaakaa Date: Mon, 27 Mar 2023 12:42:58 +0200 Subject: [PATCH 19/46] Translated using Weblate (Japanese) Currently translated at 100.0% (5759 of 5759 strings) Translation: mattermost-languages-shipped/mattermost-webapp-monorepo Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp-monorepo/ja/ Translated using Weblate (Japanese) Currently translated at 100.0% (2546 of 2546 strings) Translation: mattermost-languages-shipped/mattermost-server-monorepo Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server-monorepo/ja/ --- server/i18n/ja.json | 208 +++++++++++++++++++++++++++++++ webapp/channels/src/i18n/ja.json | 45 ++++++- 2 files changed, 248 insertions(+), 5 deletions(-) diff --git a/server/i18n/ja.json b/server/i18n/ja.json index 2f9c97f888..f42157caa1 100644 --- a/server/i18n/ja.json +++ b/server/i18n/ja.json @@ -9998,5 +9998,213 @@ { "id": "api.command_templates.unsupported.app_error", "translation": "あなたのデバイスではテンプレートコマンドはサポートされていません。" + }, + { + "id": "app.user.run.update_status.title", + "translation": "ステータスの更新" + }, + { + "id": "app.user.run.update_status.submit_label", + "translation": "ステータスを更新" + }, + { + "id": "app.user.run.update_status.reminder_for_next_update", + "translation": "次回更新のリマインド" + }, + { + "id": "app.user.run.update_status.num_channel", + "translation": { + "other": "関係者に更新内容を提供します。この投稿は {{.Count}} チャンネルに配信されます。" + } + }, + { + "id": "app.user.run.update_status.finish_run.placeholder", + "translation": "また、実行を終了としてマークする" + }, + { + "id": "app.user.run.update_status.finish_run", + "translation": "実行を終了する" + }, + { + "id": "app.user.run.update_status.change_since_last_update", + "translation": "前回更新時からの変更点" + }, + { + "id": "app.user.run.status_enable", + "translation": "@{{.Username}} は [{{.RunName}}]({{.RunURL}}) のステータス更新を有効化しました" + }, + { + "id": "app.user.run.status_disable", + "translation": "@{{.Username}} は [{{.RunName}}]({{.RunURL}}) のステータス更新を無効化しました" + }, + { + "id": "app.user.run.request_update", + "translation": "@here — @{{.Name}} は [{{.RunName}}]({{.RunURL}}) のステータスの更新を要求しました。 \n" + }, + { + "id": "app.user.run.request_join_channel", + "translation": "@{{.Name}} は実行の参加者で、このチャンネルへの参加を希望しています。チャンネルのメンバーなら誰でも招待できます。\n" + }, + { + "id": "app.user.run.confirm_finish.title", + "translation": "実行終了の確認" + }, + { + "id": "app.user.run.confirm_finish.submit_label", + "translation": "実行を終了する" + }, + { + "id": "app.user.run.confirm_finish.num_outstanding", + "translation": { + "other": "**{{.Count}} 個の未解決タスク**があります。 本当に実行 *{{.RunName}}* を終了してもよろしいですか?" + } + }, + { + "id": "app.user.run.add_to_timeline.title", + "translation": "実行のタイムラインに追加する" + }, + { + "id": "app.user.run.add_to_timeline.summary.placeholder", + "translation": "タイムラインに表示される短い要約" + }, + { + "id": "app.user.run.add_to_timeline.summary.help", + "translation": "最大 64 文字" + }, + { + "id": "app.user.run.add_to_timeline.summary", + "translation": "概要" + }, + { + "id": "app.user.run.add_to_timeline.submit_label", + "translation": "実行のタイムラインに追加する" + }, + { + "id": "app.user.run.add_to_timeline.playbook_run", + "translation": "Playbookを実行" + }, + { + "id": "app.user.run.add_checklist_item.title", + "translation": "新しいタスクを追加" + }, + { + "id": "app.user.run.add_checklist_item.submit_label", + "translation": "タスクを追加" + }, + { + "id": "app.user.run.add_checklist_item.name", + "translation": "名前" + }, + { + "id": "app.user.run.add_checklist_item.description", + "translation": "説明" + }, + { + "id": "app.user.new_run.title", + "translation": "Playbookを実行する" + }, + { + "id": "app.user.new_run.submit_label", + "translation": "実行開始" + }, + { + "id": "app.user.new_run.run_name", + "translation": "実行名" + }, + { + "id": "app.user.new_run.playbook", + "translation": "Playbook" + }, + { + "id": "app.user.new_run.intro", + "translation": "**オーナー** {{.Username}}" + }, + { + "id": "app.user.digest.tasks.zero_assigned", + "translation": "割り当てられたタスクがありません。" + }, + { + "id": "app.user.digest.tasks.num_assigned_due_until_today", + "translation": { + "other": "対応期限を迎えている{{.Count}}タスクが割り当てられています:" + } + }, + { + "id": "app.user.digest.tasks.num_assigned", + "translation": { + "other": "{{.Count}}タスクが割り当てられています:" + } + }, + { + "id": "app.user.digest.tasks.heading", + "translation": "あなたに割り当てられたタスク" + }, + { + "id": "app.user.digest.tasks.due_yesterday", + "translation": "昨日で期限切れ" + }, + { + "id": "app.user.digest.tasks.due_x_days_ago", + "translation": "{{.Count}}日前に期限切れ" + }, + { + "id": "app.user.digest.tasks.due_today", + "translation": "今日が期限です" + }, + { + "id": "app.user.digest.tasks.due_in_x_days", + "translation": { + "other": "期限は{{.Count}}日後です" + } + }, + { + "id": "app.user.digest.tasks.due_after_today", + "translation": { + "other": "**今日で期限切れとなるタスクが {{.Count}} 件**割り当てられています。" + } + }, + { + "id": "app.user.digest.tasks.all_tasks_command", + "translation": "`/playbook todo`を使用すると、あなたのすべてのタスクを確認することができます。" + }, + { + "id": "app.user.digest.runs_in_progress.zero_in_progress", + "translation": "進行中の実行はありません。" + }, + { + "id": "app.user.digest.runs_in_progress.num_in_progress", + "translation": { + "other": "現在、 {{.Count}} の実行が進行中です:" + } + }, + { + "id": "app.user.digest.runs_in_progress.heading", + "translation": "進行中の実行" + }, + { + "id": "app.user.digest.overdue_status_updates.zero_overdue", + "translation": "期限切れの実行は 0 です。" + }, + { + "id": "app.user.digest.overdue_status_updates.num_overdue", + "translation": { + "other": "ステータス更新の期日が過ぎた実行が {{.Count}} あります:" + } + }, + { + "id": "app.user.digest.overdue_status_updates.heading", + "translation": "期限切れステータスの更新" + }, + { + "id": "app.oauth.remove_auth_data_by_client_id.app_error", + "translation": "oauth データを削除することができませんでした。" + }, + { + "id": "app.command.execute.error", + "translation": "コマンドを実行できませんでした。" + }, + { + "id": "api.templates.license_up_for_renewal_contact_sales", + "translation": "営業に問い合わせる" } ] diff --git a/webapp/channels/src/i18n/ja.json b/webapp/channels/src/i18n/ja.json index 01d621261e..fee7cc2e97 100644 --- a/webapp/channels/src/i18n/ja.json +++ b/webapp/channels/src/i18n/ja.json @@ -387,7 +387,7 @@ "admin.billing.subscription.privateCloudCard.contactSalesy": "営業担当に問い合わせる", "admin.billing.subscription.privateCloudCard.contactSupport": "サポートに連絡する", "admin.billing.subscription.privateCloudCard.freeTrial.description": "私たちは、お客様のニーズにお応えすることを大切にしています。サブスクリプション、請求書作成、トライアルに関するご質問は、営業までお問い合わせください。", - "admin.billing.subscription.privateCloudCard.freeTrial.title": "トライアルに関する質問はこちら", + "admin.billing.subscription.privateCloudCard.freeTrial.title": "トライアルに関する質問がありますか?", "admin.billing.subscription.privateCloudCard.upgradeNow": "今すぐアップグレード", "admin.billing.subscription.proratedPayment.substitle": "{selectedProductName}にアップグレードしていただきありがとうございます。このプランのすべての機能にアクセスするには、数分後にワークスペースをチェックしてください。現在ご利用中の{currentProductName}プランと{selectedProductName}プランの料金については、請求サイクルの残り日数とユーザー数に応じた額を請求させていただきます。", "admin.billing.subscription.proratedPayment.title": "現在、{selectedProductName} を利用しています", @@ -1989,6 +1989,8 @@ "admin.requestButton.requestFailure": "テストが失敗しました: {error}", "admin.requestButton.requestSuccess": "テストが成功しました", "admin.reset_email.cancel": "キャンセル", + "admin.reset_email.currentPassword": "現在のパスワード", + "admin.reset_email.missing_current_password": "現在のパスワードを入力してください。", "admin.reset_email.newEmail": "新しい電子メールアドレス", "admin.reset_email.reset": "リセット", "admin.reset_email.titleReset": "電子メールを更新する", @@ -2125,7 +2127,7 @@ "admin.service.corsExposedHeadersTitle": "CORS Exposedヘッダ:", "admin.service.corsHeadersEx": "X-My-Header", "admin.service.corsTitle": "クロスオリジンリクエストを許可する:", - "admin.service.developerDesc": "有効な場合、JavaScriptのエラーはユーザーインターフェイス上部の紫色のバーに表示されます。本番環境での使用はお勧めできません。 ", + "admin.service.developerDesc": "有効な場合、JavaScriptのエラーはユーザーインターフェイス上部の紫色のバーに表示されます。本番環境での使用はお勧めできません。", "admin.service.developerTitle": "開発者モードを有効にする: ", "admin.service.disableBotOwnerDeactivatedTitle": "オーナーが無効化された際にBotアカウントを無効化する:", "admin.service.disableBotWhenOwnerIsDeactivated": "ユーザーが無効化された際、そのユーザーが管理していたすべてのBotアカウントを無効化します。Botアカウントを再び有効にするには、[統合機能 > Botアカウント]({siteURL}/_redirect/integrations/bots) から設定してください。", @@ -3128,7 +3130,7 @@ "create_post.deactivated": "**無効化されたユーザー** のいるアーカイブされたチャンネルを見ています。新しいメッセージは投稿できません。", "create_post.error_message": "メッセージが長すぎます。文字数: {length}/{limit}", "create_post.fileProcessing": "処理しています...", - "create_post.file_limit_sticky_banner.admin_message": "新たにアップロードすると古いファイルから自動的にアーカイブされます。古いファイルを削除するか、有料プランにアップグレードすることで、再度表示できるようになります。", + "create_post.file_limit_sticky_banner.admin_message": "新たにアップロードすると古いファイルから自動的にアーカイブされます。古いファイルを削除するか、有料プランにアップグレードすることで、再度表示できるようになります", "create_post.file_limit_sticky_banner.messageTitle": "無料プランではファイル容量が {storageGB} に制限されます。", "create_post.file_limit_sticky_banner.non_admin_message": "新たにアップロードすると古いファイルから自動的にアーカイブされます。再度表示するには、管理者に有料プランへアップグレードするよう通知してください。", "create_post.file_limit_sticky_banner.snooze_tooltip": "{snoozeDays}日間スヌーズする", @@ -4154,10 +4156,22 @@ "modal.manual_status.title_offline": "ステータスが \"オフライン\" になりました", "modal.manual_status.title_ooo": "ステータスが \"外出中\" になりました", "more.details": "もっと詳しく", + "more_channels.channel_purpose": "チャンネル情報: メンバーシップ状況: 加入済, メンバー数 {memberCount} , 目的: {channelPurpose}", + "more_channels.count": "{count}件", + "more_channels.count_one": "1件", + "more_channels.count_zero": "0件", "more_channels.create": "チャンネルを作成する", + "more_channels.hide_joined": "参加したことを表示しない", + "more_channels.hide_joined_checked": "チャンネルに参加したことを表示しないチェックボックスがチェック済です", + "more_channels.hide_joined_not_checked": "チャンネルに参加したことを表示しないチェックボックスがチェックされていません", + "more_channels.joined": "参加済", + "more_channels.membership_indicator": "メンバーシップ状況: 参加済", "more_channels.next": "次へ", - "more_channels.noMore": "参加できるチャンネルがありません", + "more_channels.noArchived": "アーカイブされたチャンネルはありません", + "more_channels.noMore": "\"{text}\"の結果はありません", + "more_channels.noPublic": "公開チャンネルはありません", "more_channels.prev": "前へ", + "more_channels.searchError": "違うキーワードで検索してみたり、入力ミスを確認したり、フィルター設定を変更して再度お試しください。", "more_channels.show_archived_channels": "表示: アーカイブチャンネル", "more_channels.show_public_channels": "表示: 公開チャンネル", "more_channels.title": "他のチャンネル", @@ -4367,6 +4381,7 @@ "payment_form.no_billing_address": "請求先住所が追加されませんでした", "payment_form.no_credit_card": "クレジットカードが追加されませんでした", "payment_form.saved_payment_method": "支払い方法を保存する", + "payment_form.shipping_address": "配送先住所", "payment_form.zipcode": "郵便番号", "pending_post_actions.cancel": "キャンセル", "pending_post_actions.retry": "再試行", @@ -4382,6 +4397,14 @@ "plan.self_serve": "セルフサービス", "pluggable.errorOccurred": "プラグイン {pluginId} でエラーが発生しました。", "pluggable.errorRefresh": "更新しますか?", + "pluggable_rhs.tourtip.boards.access": "右側のApp barの Boards アイコンから、リンクされた boards にアクセスできます。", + "pluggable_rhs.tourtip.boards.click": "この右側のパネルから boards をクリックします。", + "pluggable_rhs.tourtip.boards.review": "チャンネルから board の更新を確認します。", + "pluggable_rhs.tourtip.boards.title": "{count} 個のリンクされた {num, plural, one {board} other {boards}} にアクセスしましょう!", + "pluggable_rhs.tourtip.playbooks.access": "右側のApp barの Playbooks アイコンから、リンクされた playbooks にアクセスできます。", + "pluggable_rhs.tourtip.playbooks.click": "この右側のパネルから playbooks をクリックします。", + "pluggable_rhs.tourtip.playbooks.review": "チャンネルから playbook の更新を確認します。", + "pluggable_rhs.tourtip.playbooks.title": "{count} 個のリンクされた {num, plural, one {playbook} other {playbooks}} にアクセスしましょう。", "post.ariaLabel.attachment": ", 1 添付ファイル", "post.ariaLabel.attachmentMultiple": ", {attachmentCount} 添付ファイル", "post.ariaLabel.message": "{time} {date}, {authorName} が, {message} を書きました", @@ -4391,6 +4414,8 @@ "post.ariaLabel.reaction": ", 1 リアクション", "post.ariaLabel.reactionMultiple": ", {reactionCount} リアクション", "post.ariaLabel.replyMessage": "{time} {date}, {authorName} が, {message} と返信しました", + "post.reminder.acknowledgement": "{username} からのこのメッセージについて、{reminderDate}, {reminderTime} にリマインドされます: {permaLink}", + "post.reminder.systemBot": "{username} からのこのメッセージについてのリマインドです: {permaLink}", "post_body.check_for_out_of_channel_groups_mentions.message": "彼らはチャンネルにいないため、このメンションによる通知は行われませんでした。また、彼らはリンクされたグループのメンバーではないため、チャンネルに追加することもできません。彼らをこのチャンネルに追加するには、リンクされたグループに追加しなければなりません。", "post_body.check_for_out_of_channel_mentions.link.and": " と ", "post_body.check_for_out_of_channel_mentions.link.private": "彼らを非公開チャンネルに追加しますか", @@ -4431,6 +4456,13 @@ "post_info.message.visible.compact": " (あなただけが見ることができます)", "post_info.permalink": "リンクをコピーする", "post_info.pin": "チャンネルにピン留め", + "post_info.post_reminder.menu": "リマインダー", + "post_info.post_reminder.sub_menu.custom": "カスタム", + "post_info.post_reminder.sub_menu.header": "リマインダーを設定する:", + "post_info.post_reminder.sub_menu.one_hour": "1時間", + "post_info.post_reminder.sub_menu.thirty_minutes": "30分", + "post_info.post_reminder.sub_menu.tomorrow": "明日", + "post_info.post_reminder.sub_menu.two_hours": "2時間", "post_info.reply": "返信する", "post_info.submenu.icon": "サブメニューアイコン", "post_info.submenu.mobile": "モバイルサブメニュー", @@ -4459,6 +4491,9 @@ "post_priority.requested_ack.description": "メッセージに確認ボタンが表示されます", "post_priority.requested_ack.text": "確認を要求する", "post_priority.you.acknowledge": "(あなた)", + "post_reminder.custom_time_picker_modal.header": "リマインダーを設定する", + "post_reminder.custom_time_picker_modal.submit_button": "リマインダーを設定する", + "post_reminder_custom_time_picker_modal.defaultMsg": "リマインダーを設定する", "postlist.toast.history": "メッセージの履歴を確認しています", "postlist.toast.newMessages": "新しい {count, number} {count, plural, one {メッセージ} other {メッセージ}}", "postlist.toast.newMessagesSince": "{date} {isToday, select, true {} other {以降}} に投稿された新しい {count, number} {count, plural, one {メッセージ} other {メッセージ}}", @@ -5385,7 +5420,7 @@ "user.settings.notifications.email.disabled": "電子メール通知は有効化されていません", "user.settings.notifications.email.disabled_long": "電子メール通知はシステム管理者によって有効化されていません。", "user.settings.notifications.email.everyHour": "1時間毎", - "user.settings.notifications.email.everyXMinutes": "{count}分ごと", + "user.settings.notifications.email.everyXMinutes": "{count, plural, one {分} other {{count, number} 分}}ごと", "user.settings.notifications.email.immediately": "すぐに", "user.settings.notifications.email.never": "通知しない", "user.settings.notifications.email.send": "電子メール通知を送信する", From 5c4f1b5bde8c022668d51741f064b75ed63fabda Mon Sep 17 00:00:00 2001 From: jprusch Date: Mon, 27 Mar 2023 12:42:58 +0200 Subject: [PATCH 20/46] Translated using Weblate (German) Currently translated at 100.0% (5759 of 5759 strings) Translation: mattermost-languages-shipped/mattermost-webapp-monorepo Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp-monorepo/de/ Translated using Weblate (German) Currently translated at 100.0% (2546 of 2546 strings) Translation: mattermost-languages-shipped/mattermost-server-monorepo Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server-monorepo/de/ --- server/i18n/de.json | 208 +++++++++++++++++++++++++++++++ webapp/channels/src/i18n/de.json | 19 ++- 2 files changed, 224 insertions(+), 3 deletions(-) diff --git a/server/i18n/de.json b/server/i18n/de.json index b5e9251adc..7d7cefc91d 100644 --- a/server/i18n/de.json +++ b/server/i18n/de.json @@ -10013,5 +10013,213 @@ { "id": "app.oauth.remove_auth_data_by_client_id.app_error", "translation": "Oauth-Daten können nicht entfernt werden." + }, + { + "id": "app.user.run.update_status.title", + "translation": "Aktueller Stand" + }, + { + "id": "app.user.run.update_status.submit_label", + "translation": "Status aktualisieren" + }, + { + "id": "app.user.run.update_status.reminder_for_next_update", + "translation": "Erinnerung an das nächste Update" + }, + { + "id": "app.user.run.update_status.num_channel", + "translation": { + "one": "Bringe die Beteiligten auf den neuesten Stand. Dieser Beitrag wird in einem Kanal veröffentlicht.", + "other": "Bringe die Beteiligten auf den neuesten Stand. Dieser Beitrag wird in {{.Count}} Kanälen veröffentlicht." + } + }, + { + "id": "app.user.run.update_status.finish_run.placeholder", + "translation": "Markiere den Durchlauf auch als beendet" + }, + { + "id": "app.user.run.update_status.finish_run", + "translation": "Durchlauf beenden" + }, + { + "id": "app.user.run.update_status.change_since_last_update", + "translation": "Änderung seit der letzten Aktualisierung" + }, + { + "id": "app.user.run.status_enable", + "translation": "@{{.Username}} hat die Statusaktualisierungen für [{{.RunName}}]({{.RunURL}}) aktiviert" + }, + { + "id": "app.user.run.status_disable", + "translation": "@{{.Username}} hat die Statusaktualisierungen für [{{.RunName}}]({{.RunURL}}) deaktiviert" + }, + { + "id": "app.user.run.request_update", + "translation": "@here — @{{.Name}} hat eine Statusaktualisierung für [{{.RunName}}]({{.RunURL}}) angefordert. \n" + }, + { + "id": "app.user.run.request_join_channel", + "translation": "@{{.Name}} ist ein Teilnehmer und möchte diesem Kanal beitreten. Jedes Mitglied des Kanals kann ihn einladen.\n" + }, + { + "id": "app.user.run.confirm_finish.title", + "translation": "Beenden des Durchlaufs bestätigen" + }, + { + "id": "app.user.run.confirm_finish.submit_label", + "translation": "Durchlauf beenden" + }, + { + "id": "app.user.run.confirm_finish.num_outstanding", + "translation": { + "one": "Es gibt **eine offene Aufgabe**. Bist du sicher, dass du den Durchlauf *{{.RunName}}* für alle Teilnehmer beenden willst?", + "other": "Es gibt **{{.Count}} offene Aufgaben**. Bist du sicher, dass du den Durchlauf *{{.RunName}}* für alle Teilnehmer beenden willst?" + } + }, + { + "id": "app.user.run.add_to_timeline.title", + "translation": "Zur Zeitleiste hinzufügen" + }, + { + "id": "app.user.run.add_to_timeline.summary.placeholder", + "translation": "Kurze Zusammenfassung auf der Zeitachse" + }, + { + "id": "app.user.run.add_to_timeline.summary.help", + "translation": "Max. 64 Zeichen" + }, + { + "id": "app.user.run.add_to_timeline.summary", + "translation": "Zusammenfassung" + }, + { + "id": "app.user.run.add_to_timeline.submit_label", + "translation": "Zur Zeitleiste hinzufügen" + }, + { + "id": "app.user.run.add_to_timeline.playbook_run", + "translation": "Playbook-Durchlauf" + }, + { + "id": "app.user.run.add_checklist_item.title", + "translation": "Neue Aufgabe hinzufügen" + }, + { + "id": "app.user.run.add_checklist_item.submit_label", + "translation": "Aufgabe hinzufügen" + }, + { + "id": "app.user.run.add_checklist_item.name", + "translation": "Name" + }, + { + "id": "app.user.run.add_checklist_item.description", + "translation": "Beschreibung" + }, + { + "id": "app.user.new_run.title", + "translation": "Playbook starten" + }, + { + "id": "app.user.new_run.submit_label", + "translation": "Starte Durchlauf" + }, + { + "id": "app.user.new_run.run_name", + "translation": "Name des Durchlaufs" + }, + { + "id": "app.user.new_run.playbook", + "translation": "Playbook" + }, + { + "id": "app.user.new_run.intro", + "translation": "**Eigentümer** {{.Username}}" + }, + { + "id": "app.user.digest.tasks.zero_assigned", + "translation": "Du hast keine zugewiesene Aufgabe." + }, + { + "id": "app.user.digest.tasks.num_assigned_due_until_today", + "translation": { + "one": "Du hast eine zugewiesene Aufgabe, die jetzt fällig ist:", + "other": "Du hast {{.Count}} zugewiesene Aufgaben, die jetzt fällig sind:" + } + }, + { + "id": "app.user.digest.tasks.num_assigned", + "translation": { + "one": "Du hast eine zugewiesene Aufgabe:", + "other": "Du hast {{.Count}} zugewiesene Aufgaben:" + } + }, + { + "id": "app.user.digest.tasks.heading", + "translation": "Deine zugewiesenen Aufgaben" + }, + { + "id": "app.user.digest.tasks.due_yesterday", + "translation": "Gestern fällig" + }, + { + "id": "app.user.digest.tasks.due_x_days_ago", + "translation": "Fällig vor {{.Count}} Tagen" + }, + { + "id": "app.user.digest.tasks.due_today", + "translation": "Heute fällig" + }, + { + "id": "app.user.digest.tasks.due_in_x_days", + "translation": { + "one": "Fällig in einem Tag", + "other": "Fällig in {{.Count}} Tagen" + } + }, + { + "id": "app.user.digest.tasks.due_after_today", + "translation": { + "one": "Du hast **eine zugewiesene Aufgabe, die nach dem heutige Tag fällig ist**.", + "other": "Du hast **{{.Count}} zugewiesene Aufgaben, die nach dem heutige Tag fällig sind**." + } + }, + { + "id": "app.user.digest.tasks.all_tasks_command", + "translation": "Bitte benutze `/playbook todo` um alle deine Aufgaben anzuzeigen." + }, + { + "id": "app.user.digest.runs_in_progress.zero_in_progress", + "translation": "Du hast keinen aktiven Durchlauf." + }, + { + "id": "app.user.digest.runs_in_progress.num_in_progress", + "translation": { + "one": "Du hast einen aktiven Durchlauf:", + "other": "Du hast {{.Count}} aktive Durchläufe:" + } + }, + { + "id": "app.user.digest.runs_in_progress.heading", + "translation": "Aktive Durchläufe" + }, + { + "id": "app.user.digest.overdue_status_updates.zero_overdue", + "translation": "Du hast keine überfälligen Durchläufe." + }, + { + "id": "app.user.digest.overdue_status_updates.num_overdue", + "translation": { + "one": "Du hast einen überfälligen Durchlauf für ein Statusupdate:", + "other": "Du hast {{.Count}} überfällige Durchläufe für ein Statusupdate:" + } + }, + { + "id": "app.user.digest.overdue_status_updates.heading", + "translation": "Überfällige Statusaktualisierungen" + }, + { + "id": "app.command.execute.error", + "translation": "Kann Befehl nicht ausführen." } ] diff --git a/webapp/channels/src/i18n/de.json b/webapp/channels/src/i18n/de.json index a9ab534958..01990e3010 100644 --- a/webapp/channels/src/i18n/de.json +++ b/webapp/channels/src/i18n/de.json @@ -2127,7 +2127,7 @@ "admin.service.corsExposedHeadersTitle": "CORS-Exposed-Headers:", "admin.service.corsHeadersEx": "X-My-Header", "admin.service.corsTitle": "Erlaube Cross Origin Requests von:", - "admin.service.developerDesc": "Wenn wahr, werden Javascript Fehler in einer roten Zeile im oberen Bereich des Interfaces angezeigt. Nicht empfohlen für Produktionsumgebungen. ", + "admin.service.developerDesc": "Wenn wahr, werden Javascript Fehler in einer roten Zeile im oberen Bereich des Interfaces angezeigt. Nicht empfohlen für Produktionsumgebungen. Das Ändern dieser Einstellung erfordert einen Neustart des Servers, bevor sie wirksam wird.", "admin.service.developerTitle": "Aktiviere Entwickler-Modus: ", "admin.service.disableBotOwnerDeactivatedTitle": "Deaktiviere Bot-Konten, wenn der Besitzer deaktiviert ist:", "admin.service.disableBotWhenOwnerIsDeactivated": "Wenn ein Benutzer deaktiviert ist, werden alle vom Benutzer verwalteten Bot-Konten deaktiviert. Um Bot-Konten wieder zu aktivieren, gehe zu [Integrationen > Bot-Konten]({siteURL}/_redirect/integrations/bots).", @@ -3603,7 +3603,7 @@ "help.attaching.pasting.title": "Kopieren und Einfügen von Dateien", "help.attaching.previewer.description": "Mattermost verfügt über eine integrierte Dateivorschau, die zum Anzeigen von Medien, Herunterladen von Dateien und zum Teilen öffentlicher Links verwendet wird. Wähle die Miniaturansicht einer angehängten Datei, um sie in der Dateivorschau zu öffnen.", "help.attaching.previewer.title": "Dateivorschau", - "help.attaching.publicLinks.description": "Mit öffentlichen Links kannst du Dateianhänge mit Personen außerhalb deines Mattermost-Teams teilen. Öffne die Dateivorschau, indem du die Miniaturansicht eines Anhangs auswählen, und wähle dann **Öffentlichen Link erhalten**. Kopiere den angegebenen Link. Wenn der Link freigegeben und von einem anderen Benutzer geöffnet wird, wird die Datei automatisch heruntergeladen.", + "help.attaching.publicLinks.description": "Mit öffentlichen Links kannst du Dateianhänge mit Personen außerhalb deines Mattermost-Teams teilen. Öffne die Dateivorschau, indem du die Miniaturansicht eines Anhangs auswählen, und wähle dann **Öffentlichen Link erhalten**. Kopiere den angegebenen Link. Wenn der Link geteilt und von einem anderen Benutzer geöffnet wird, erfolgt ein automatischer Download der Datei.", "help.attaching.publicLinks.title": "Links öffentlich teilen", "help.attaching.publicLinks2": "Wenn die Option **Öffentlichen Link abrufen** in der Dateivorschau nicht sichtbar ist und du diese Funktion aktivieren möchtest, bitten deinen Systemadministrator, diese Funktion in der Systemkonsole unter **Site-Konfiguration > Öffentliche Links** zu aktivieren.", "help.attaching.supported.description": "Wenn du versuchst, eine Vorschau eines nicht unterstützten Medientyps anzuzeigen, öffnet die Dateivorschau ein Standardsymbol für Medienanhänge. Die unterstützten Medienformate hängen stark von deinem Browser und Betriebssystem ab. Die folgenden Formate werden von Mattermost in den meisten Browsern unterstützt:", @@ -4156,10 +4156,22 @@ "modal.manual_status.title_offline": "Dein Status wurde auf \"Offline\" gesetzt", "modal.manual_status.title_ooo": "Dein Status ist auf \"Nicht im Büro\" gesetzt", "more.details": "Mehr Details", + "more_channels.channel_purpose": "Kanal-Informationen: Mitgliedschaftsindikator: Beigetreten, Mitglieder {memberCount}, Zweck: {channelPurpose}", + "more_channels.count": "{count} Ergebnisse", + "more_channels.count_one": "1 Ergebnis", + "more_channels.count_zero": "Keine Ergebnisse", "more_channels.create": "Kanal erstellen", + "more_channels.hide_joined": "Verbundene Kanäle ausblenden", + "more_channels.hide_joined_checked": "Kontrollkästchen Verbundene Kanäle ausblenden, aktiviert", + "more_channels.hide_joined_not_checked": "Kontrollkästchen Verbundene Kanäle ausblenden, deaktiviert", + "more_channels.joined": "Verknüpft", + "more_channels.membership_indicator": "Mitgliedschaftsindikator: Beigetreten", "more_channels.next": "Weiter", - "more_channels.noMore": "Keine weiteren Kanäle, denen beigetreten werden kann", + "more_channels.noArchived": "Keine archivierten Kanäle", + "more_channels.noMore": "Keine Ergebnisse für \"{text}\"", + "more_channels.noPublic": "Keine öffentlichen Kanäle", "more_channels.prev": "Zurück", + "more_channels.searchError": "Versuche, nach anderen Stichworten zu suchen, auf Tippfehlern zu prüfen oder die Filter anzupassen.", "more_channels.show_archived_channels": "Anzeigen: Archivierte Kanäle", "more_channels.show_public_channels": "Anzeigen: Öffentliche Kanäle", "more_channels.title": "Weitere Kanäle", @@ -4369,6 +4381,7 @@ "payment_form.no_billing_address": "Keine Rechnungsadresse hinzugefügt", "payment_form.no_credit_card": "Keine Kreditkarte hinzugefügt", "payment_form.saved_payment_method": "Zahlungsmethode speichern", + "payment_form.shipping_address": "Lieferadresse", "payment_form.zipcode": "Postleitzahl/Zip", "pending_post_actions.cancel": "Abbrechen", "pending_post_actions.retry": "Erneut versuchen", From d62244aebb79ea487851510e67fc01066c9a6ea8 Mon Sep 17 00:00:00 2001 From: master7 Date: Mon, 27 Mar 2023 12:42:59 +0200 Subject: [PATCH 21/46] Translated using Weblate (Polish) Currently translated at 100.0% (5759 of 5759 strings) Translation: mattermost-languages-shipped/mattermost-webapp-monorepo Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp-monorepo/pl/ Translated using Weblate (Polish) Currently translated at 98.3% (2505 of 2546 strings) Translation: mattermost-languages-shipped/mattermost-server-monorepo Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-server-monorepo/pl/ --- server/i18n/pl.json | 24 ++++++++++++++++++++++++ webapp/channels/src/i18n/pl.json | 17 +++++++++++++++-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/server/i18n/pl.json b/server/i18n/pl.json index 31a6bc7aeb..9049ed5e57 100644 --- a/server/i18n/pl.json +++ b/server/i18n/pl.json @@ -10014,5 +10014,29 @@ { "id": "app.oauth.remove_auth_data_by_client_id.app_error", "translation": "Nie można usunąć danych oauth." + }, + { + "id": "app.user.digest.runs_in_progress.heading", + "translation": "Uruchomienia w Trakcie" + }, + { + "id": "app.user.digest.overdue_status_updates.zero_overdue", + "translation": "Masz 0 zaległych uruchomień." + }, + { + "id": "app.user.digest.overdue_status_updates.num_overdue", + "translation": { + "few": "Masz {{.Count}} zaległości w aktualizacji statusu:", + "many": "Masz {{.Count}} zaległości w aktualizacji statusu:", + "one": "Masz {{.Count}} zaległość w aktualizacji statusu:" + } + }, + { + "id": "app.user.digest.overdue_status_updates.heading", + "translation": "Zaległe aktualizacje statusu" + }, + { + "id": "app.command.execute.error", + "translation": "Nie można wykonać polecenia." } ] diff --git a/webapp/channels/src/i18n/pl.json b/webapp/channels/src/i18n/pl.json index 7786f19479..96eda0f3b4 100644 --- a/webapp/channels/src/i18n/pl.json +++ b/webapp/channels/src/i18n/pl.json @@ -2127,7 +2127,7 @@ "admin.service.corsExposedHeadersTitle": "Eksponowane nagłówki CORS:", "admin.service.corsHeadersEx": "X-Mój-Header", "admin.service.corsTitle": "Pozwól na zapytania Cross-domain z:", - "admin.service.developerDesc": "Gdy włączone, błędy JavaScript wyświetlane są na czerwonym pasku u góry interfejsu użytkownika. Nie zalecane w wersji produkcyjnej. ", + "admin.service.developerDesc": "Gdy włączone, błędy JavaScript wyświetlane są na czerwonym pasku u góry interfejsu użytkownika. Nie zalecane w wersji produkcyjnej. Zmiana tego wymaga restartu serwera zanim zacznie działać.", "admin.service.developerTitle": "Włączyć Tryb Dewelopera: ", "admin.service.disableBotOwnerDeactivatedTitle": "Wyłącz konta botów jeśli właściciel jest dezaktywowany:", "admin.service.disableBotWhenOwnerIsDeactivated": "Kiedy użytkownik jest dezaktywowany, wyłącza wszystkie konta bot zarządzane przez użytkownika. Aby ponownie włączyć konta botów, przejdź do [Integracje > Konta Botów]({siteURL}/_redirect/integrations/bots).", @@ -4156,10 +4156,22 @@ "modal.manual_status.title_offline": "Twój status został ustawiony na \"Offline\"", "modal.manual_status.title_ooo": "Twój status został ustawiony na \"Poza biurem\"", "more.details": "Więcej informacji", + "more_channels.channel_purpose": "Informacje o kanale: Wskaźnik członkostwa: Dołączyło, liczba członków {memberCount}, Propozycje: {channelPurpose}", + "more_channels.count": "{count} Wyników", + "more_channels.count_one": "1 Wynik", + "more_channels.count_zero": "0 Wyników", "more_channels.create": "Stwórz kanał", + "more_channels.hide_joined": "Ukryj dołączonych", + "more_channels.hide_joined_checked": "Pole wyboru Ukryj połączone kanały, zaznaczone", + "more_channels.hide_joined_not_checked": "Pole wyboru Ukryj połączone kanały, nie zaznaczone", + "more_channels.joined": "Dołączył", + "more_channels.membership_indicator": "Wskaźnik członkostwa: Dołączył", "more_channels.next": "Dalej", - "more_channels.noMore": "Brak kanałów", + "more_channels.noArchived": "Brak zarchiwizowanych kanałów", + "more_channels.noMore": "Brak wyników dla \"{text}\"", + "more_channels.noPublic": "Brak kanałów publicznych", "more_channels.prev": "Wstecz", + "more_channels.searchError": "Spróbuj wyszukać inne słowa kluczowe, sprawdzić literówki lub dostosować filtry.", "more_channels.show_archived_channels": "Pokaż: Archiwizowane kanały", "more_channels.show_public_channels": "Pokaż: Publiczne kanały", "more_channels.title": "Więcej Kanałów", @@ -4369,6 +4381,7 @@ "payment_form.no_billing_address": "Nie dodano adresu rozliczeniowego", "payment_form.no_credit_card": "Nie dodano karty kredytowej", "payment_form.saved_payment_method": "Zapisana Metoda Płatności", + "payment_form.shipping_address": "Adres do wysyłki", "payment_form.zipcode": "Kod Pocztowy", "pending_post_actions.cancel": "Anuluj", "pending_post_actions.retry": "Ponów", From 80c14319838bc6d8a83c3e44d9292a6982d3be38 Mon Sep 17 00:00:00 2001 From: Jesse Hallam Date: Mon, 27 Mar 2023 13:19:29 -0300 Subject: [PATCH 22/46] Revert testing workarounds (#22630) * Revert "fix store issue take two" This reverts commit 59f943c2c7ff7d88f7b36cc29e242042746e959e. * Revert "fix store override issue" This reverts commit 29c346757aa627c07d357c54991f9188c927dd1a. * Revert "Fix TestPushNotificationRace" This reverts commit 6d62dddf8679e82b02e8ad9fe7513217eef5b4ee. * Revert "fix default DSN for CI" This reverts commit e0e69cdbb0645bb50434f6b5bbd12bead1e7ce1d. * Revert "disable playbooks from more unit tests" This reverts commit a1e97a9e96bdd16537f5b6dbdc8335762617a9e0. * Revert "disable playbooks for more tests" This reverts commit 4d2dc74f05339f0b3cd28b997a2e35ae20f898be. * Revert "disable playbooks for TestSAMLSettings" This reverts commit 35c1a4312d0c6a0a64991520fa5b0892c083e6a1. * Revert "disable playbooks for more unit tests" This reverts commit c049631a1474cddf168b2be8feb24140e0dcfd48. * Revert "disable playbooks for mocked enterprise tests" This reverts commit 829317fddbd0e84866534a5a75e52dcffd2dbde7. * Partially revert "disable playbooks for channel/apps mocked tests" This reverts commit 52b4a0a6cf135d26f53298294ed23734aafae0d2. * Revert "fix TestUnitUpdateConfig" This reverts commit 8f134f2a8ae9765aa2b6f66d6827e10ef1f5109f. * Revert "add plugin mock to TestUnitUpdateConfig" This reverts commit 3ec5419092135f494fd04701b5cbbd15920e667b. * Revert "disable Boards for more test helpers" This reverts commit 5d4d0d02d9cf6f872f0304098c68a01a3aab0fbe. * Revert "disable boards at correct place in test helpers" This reverts commit 0c9e175f79293c8be4289c7424930388f207dc75. * Partially revert "disable boards for slash cmd tests" This reverts commit fad8d9de93f5ce351d2e50fd6448662e75f597ae. * Revert "disable Boards for channels web tests" This reverts commit 15540fdfc09cf927071af718d4ad0b2c58308328. * Revert "Adds a teardown function to playbook server tests to disable and reenable boards" This reverts commit 9a46e3d0f43f66d548994986b8c4029d58ad022f. * Revert "Test disable boards through feature flag" This reverts commit 787044add8ba8e2680a2c3c6ba11e709cebc8705. * TestUnitUpdateConfig: restore callback check * Revert "Revert "fix default DSN for CI"" This reverts commit 01b879d55ad1249265f23c6fd9ceb5d7730ddb3d. --- server/channels/api4/apitestlib.go | 44 ++++-------------- server/channels/app/app_test.go | 21 ++++++++- server/channels/app/helper_test.go | 46 ++++++------------- server/channels/app/notification_push_test.go | 10 ++-- server/channels/app/product.go | 6 +-- .../channels/app/slashcommands/helper_test.go | 40 +++------------- server/channels/web/web_test.go | 39 +++------------- server/playbooks/server/api_actions_test.go | 9 ++-- server/playbooks/server/api_bot_test.go | 3 +- server/playbooks/server/api_general_test.go | 3 +- .../server/api_graphql_playbooks_test.go | 12 ++--- .../playbooks/server/api_graphql_runs_test.go | 27 ++++------- server/playbooks/server/api_playbooks_test.go | 45 ++++++------------ server/playbooks/server/api_runs_test.go | 39 ++++++---------- server/playbooks/server/api_settings_test.go | 3 +- server/playbooks/server/api_stats_test.go | 6 +-- server/playbooks/server/api_telemetry_test.go | 3 +- server/playbooks/server/main_test.go | 16 ++----- 18 files changed, 113 insertions(+), 259 deletions(-) diff --git a/server/channels/api4/apitestlib.go b/server/channels/api4/apitestlib.go index 92ef4a9221..921ceb0a2c 100644 --- a/server/channels/api4/apitestlib.go +++ b/server/channels/api4/apitestlib.go @@ -71,10 +71,8 @@ type TestHelper struct { IncludeCacheLayer bool - LogBuffer *mlog.Buffer - TestLogger *mlog.Logger - boardsProductEnvValue string - playbooksDisableEnvValue string + LogBuffer *mlog.Buffer + TestLogger *mlog.Logger } var mainHelper *testlib.MainHelper @@ -104,17 +102,6 @@ func setupTestHelper(dbStore store.Store, searchEngine *searchengine.Broker, ent *memoryConfig.AnnouncementSettings.AdminNoticesEnabled = false *memoryConfig.AnnouncementSettings.UserNoticesEnabled = false *memoryConfig.PluginSettings.AutomaticPrepackagedPlugins = false - - // disable Boards through the feature flag - boardsProductEnvValue := os.Getenv("MM_FEATUREFLAGS_BoardsProduct") - os.Unsetenv("MM_FEATUREFLAGS_BoardsProduct") - memoryConfig.FeatureFlags.BoardsProduct = false - - // disable Playbooks (temporarily) as it causes many more mocked methods to get - // called, and cannot receieve a mocked database. - playbooksDisableEnvValue := os.Getenv("MM_DISABLE_PLAYBOOKS") - os.Setenv("MM_DISABLE_PLAYBOOKS", "true") - if updateConfig != nil { updateConfig(memoryConfig) } @@ -153,15 +140,13 @@ func setupTestHelper(dbStore store.Store, searchEngine *searchengine.Broker, ent } th := &TestHelper{ - App: app.New(app.ServerConnector(s.Channels())), - Server: s, - ConfigStore: configStore, - IncludeCacheLayer: includeCache, - Context: request.EmptyContext(testLogger), - TestLogger: testLogger, - LogBuffer: buffer, - boardsProductEnvValue: boardsProductEnvValue, - playbooksDisableEnvValue: playbooksDisableEnvValue, + App: app.New(app.ServerConnector(s.Channels())), + Server: s, + ConfigStore: configStore, + IncludeCacheLayer: includeCache, + Context: request.EmptyContext(testLogger), + TestLogger: testLogger, + LogBuffer: buffer, } th.Context.SetLogger(testLogger) @@ -386,17 +371,6 @@ func (th *TestHelper) ShutdownApp() { } func (th *TestHelper) TearDown() { - // reset board and playbooks product setting to original - if th.boardsProductEnvValue != "" { - os.Setenv("MM_FEATUREFLAGS_BoardsProduct", th.boardsProductEnvValue) - } - - if th.playbooksDisableEnvValue != "" { - os.Setenv("MM_DISABLE_PLAYBOOKS", th.playbooksDisableEnvValue) - } else { - os.Unsetenv("MM_DISABLE_PLAYBOOKS") - } - if th.IncludeCacheLayer { // Clean all the caches th.App.Srv().InvalidateAllCaches() diff --git a/server/channels/app/app_test.go b/server/channels/app/app_test.go index 70a29f3985..ff725fecdf 100644 --- a/server/channels/app/app_test.go +++ b/server/channels/app/app_test.go @@ -11,8 +11,10 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" "github.com/mattermost/mattermost-server/v6/model" + "github.com/mattermost/mattermost-server/v6/server/channels/store/storetest/mocks" ) /* Temporarily comment out until MM-11108 @@ -37,9 +39,26 @@ func init() { } func TestUnitUpdateConfig(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() + mockStore := th.App.Srv().Store().(*mocks.Store) + mockUserStore := mocks.UserStore{} + mockUserStore.On("Count", mock.Anything).Return(int64(10), nil) + mockPostStore := mocks.PostStore{} + mockPostStore.On("GetMaxPostSize").Return(65535, nil) + mockSystemStore := mocks.SystemStore{} + mockSystemStore.On("GetByName", "UpgradedFromTE").Return(&model.System{Name: "UpgradedFromTE", Value: "false"}, nil) + mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil) + mockSystemStore.On("GetByName", "FirstServerRunTimestamp").Return(&model.System{Name: "FirstServerRunTimestamp", Value: "10"}, nil) + mockLicenseStore := mocks.LicenseStore{} + mockLicenseStore.On("Get", "").Return(&model.LicenseRecord{}, nil) + mockStore.On("User").Return(&mockUserStore) + mockStore.On("Post").Return(&mockPostStore) + mockStore.On("System").Return(&mockSystemStore) + mockStore.On("License").Return(&mockLicenseStore) + mockStore.On("GetDBSchemaVersion").Return(1, nil) + prev := *th.App.Config().ServiceSettings.SiteURL var called int32 diff --git a/server/channels/app/helper_test.go b/server/channels/app/helper_test.go index 4b5cf1aa0b..a1b8340f66 100644 --- a/server/channels/app/helper_test.go +++ b/server/channels/app/helper_test.go @@ -42,9 +42,7 @@ type TestHelper struct { TestLogger *mlog.Logger IncludeCacheLayer bool - tempWorkspace string - boardsProductEnvValue string - playbooksDisableEnvValue string + tempWorkspace string } func setupTestHelper(dbStore store.Store, enterprise bool, includeCacheLayer bool, options []Option, tb testing.TB) *TestHelper { @@ -62,17 +60,6 @@ func setupTestHelper(dbStore store.Store, enterprise bool, includeCacheLayer boo *memoryConfig.LogSettings.EnableSentry = false // disable error reporting during tests *memoryConfig.AnnouncementSettings.AdminNoticesEnabled = false *memoryConfig.AnnouncementSettings.UserNoticesEnabled = false - - // disable Boards through the feature flag - boardsProductEnvValue := os.Getenv("MM_FEATUREFLAGS_BoardsProduct") - os.Unsetenv("MM_FEATUREFLAGS_BoardsProduct") - memoryConfig.FeatureFlags.BoardsProduct = false - - // disable Playbooks (temporarily) as it causes many more mocked methods to get - // called, and cannot receieve a mocked database. - playbooksDisableEnvValue := os.Getenv("MM_DISABLE_PLAYBOOKS") - os.Setenv("MM_DISABLE_PLAYBOOKS", "true") - configStore.Set(memoryConfig) buffer := &mlog.Buffer{} @@ -103,14 +90,12 @@ func setupTestHelper(dbStore store.Store, enterprise bool, includeCacheLayer boo } th := &TestHelper{ - App: New(ServerConnector(s.Channels())), - Context: request.EmptyContext(testLogger), - Server: s, - LogBuffer: buffer, - TestLogger: testLogger, - IncludeCacheLayer: includeCacheLayer, - boardsProductEnvValue: boardsProductEnvValue, - playbooksDisableEnvValue: playbooksDisableEnvValue, + App: New(ServerConnector(s.Channels())), + Context: request.EmptyContext(testLogger), + Server: s, + LogBuffer: buffer, + TestLogger: testLogger, + IncludeCacheLayer: includeCacheLayer, } th.Context.SetLogger(testLogger) @@ -184,10 +169,16 @@ func SetupWithStoreMock(tb testing.TB) *TestHelper { statusMock.On("Get", "user1").Return(&model.Status{UserId: "user1", Status: model.StatusOnline}, nil) statusMock.On("UpdateLastActivityAt", "user1", mock.Anything).Return(nil) statusMock.On("SaveOrUpdate", mock.AnythingOfType("*model.Status")).Return(nil) + + pluginMock := mocks.PluginStore{} + pluginMock.On("Get", mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return(&model.PluginKeyValue{}, nil) + emptyMockStore := mocks.Store{} emptyMockStore.On("Close").Return(nil) emptyMockStore.On("Status").Return(&statusMock) + emptyMockStore.On("Plugin").Return(&pluginMock).Maybe() th.App.Srv().SetStore(&emptyMockStore) + return th } @@ -553,17 +544,6 @@ func (th *TestHelper) ShutdownApp() { } func (th *TestHelper) TearDown() { - // reset board and playbooks product setting to original - if th.boardsProductEnvValue != "" { - os.Setenv("MM_FEATUREFLAGS_BoardsProduct", th.boardsProductEnvValue) - } - - if th.playbooksDisableEnvValue != "" { - os.Setenv("MM_DISABLE_PLAYBOOKS", th.playbooksDisableEnvValue) - } else { - os.Unsetenv("MM_DISABLE_PLAYBOOKS") - } - if th.IncludeCacheLayer { // Clean all the caches th.App.Srv().InvalidateAllCaches() diff --git a/server/channels/app/notification_push_test.go b/server/channels/app/notification_push_test.go index ed22c833eb..8c42bdbbca 100644 --- a/server/channels/app/notification_push_test.go +++ b/server/channels/app/notification_push_test.go @@ -1445,13 +1445,9 @@ func TestPushNotificationRace(t *testing.T) { Router: mux.NewRouter(), } var err error - s.platform, err = platform.New( - platform.ServiceConfig{ - ConfigStore: memoryStore, - }, - platform.SetFileStore(&fmocks.FileBackend{}), - platform.StoreOverride(th.GetSqlStore()), - ) + s.platform, err = platform.New(platform.ServiceConfig{ + ConfigStore: memoryStore, + }, platform.SetFileStore(&fmocks.FileBackend{})) s.SetStore(mockStore) require.NoError(t, err) serviceMap := map[product.ServiceKey]any{ diff --git a/server/channels/app/product.go b/server/channels/app/product.go index af515fe290..37d4af8c5b 100644 --- a/server/channels/app/product.go +++ b/server/channels/app/product.go @@ -73,17 +73,15 @@ func (s *Server) initializeProducts( func (s *Server) shouldStart(product string) bool { if product == "boards" { if !s.Config().FeatureFlags.BoardsProduct { - s.Log().Info("Skipping Boards init; disabled via feature flag") + s.Log().Warn("Skipping boards start: not enabled via feature flag") return false } - s.Log().Info("Allowing Boards init; enabled via feature flag") } if product == "playbooks" { if os.Getenv("MM_DISABLE_PLAYBOOKS") == "true" { - s.Log().Info("Skipping Playbooks init; disabled via env var") + s.Log().Warn("Skipping playbooks start: disabled via env var") return false } - s.Log().Info("Allowing Playbooks init; enabled via env var") } return true diff --git a/server/channels/app/slashcommands/helper_test.go b/server/channels/app/slashcommands/helper_test.go index cc0960cee6..af574c5cce 100644 --- a/server/channels/app/slashcommands/helper_test.go +++ b/server/channels/app/slashcommands/helper_test.go @@ -36,9 +36,7 @@ type TestHelper struct { TestLogger *mlog.Logger IncludeCacheLayer bool - tempWorkspace string - boardsProductEnvValue string - playbooksDisableEnvValue string + tempWorkspace string } func setupTestHelper(dbStore store.Store, enterprise bool, includeCacheLayer bool, tb testing.TB, configSet func(*model.Config)) *TestHelper { @@ -53,17 +51,6 @@ func setupTestHelper(dbStore store.Store, enterprise bool, includeCacheLayer boo if configSet != nil { configSet(memoryConfig) } - - // disable Boards through the feature flag - boardsProductEnvValue := os.Getenv("MM_FEATUREFLAGS_BoardsProduct") - os.Unsetenv("MM_FEATUREFLAGS_BoardsProduct") - memoryConfig.FeatureFlags.BoardsProduct = false - - // disable Playbooks (temporarily) as it causes many more mocked methods to get - // called, and cannot receieve a mocked database. - playbooksDisableEnvValue := os.Getenv("MM_DISABLE_PLAYBOOKS") - os.Setenv("MM_DISABLE_PLAYBOOKS", "true") - *memoryConfig.PluginSettings.Directory = filepath.Join(tempWorkspace, "plugins") *memoryConfig.PluginSettings.ClientDirectory = filepath.Join(tempWorkspace, "webapp") *memoryConfig.PluginSettings.AutomaticPrepackagedPlugins = false @@ -95,14 +82,12 @@ func setupTestHelper(dbStore store.Store, enterprise bool, includeCacheLayer boo } th := &TestHelper{ - App: app.New(app.ServerConnector(s.Channels())), - Context: request.EmptyContext(testLogger), - Server: s, - LogBuffer: buffer, - TestLogger: testLogger, - IncludeCacheLayer: includeCacheLayer, - boardsProductEnvValue: boardsProductEnvValue, - playbooksDisableEnvValue: playbooksDisableEnvValue, + App: app.New(app.ServerConnector(s.Channels())), + Context: request.EmptyContext(testLogger), + Server: s, + LogBuffer: buffer, + TestLogger: testLogger, + IncludeCacheLayer: includeCacheLayer, } th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.MaxUsersPerTeam = 50 }) @@ -389,17 +374,6 @@ func (th *TestHelper) shutdownApp() { } func (th *TestHelper) tearDown() { - // reset board and playbooks product setting to original - if th.boardsProductEnvValue != "" { - os.Setenv("MM_FEATUREFLAGS_BoardsProduct", th.boardsProductEnvValue) - } - - if th.playbooksDisableEnvValue != "" { - os.Setenv("MM_DISABLE_PLAYBOOKS", th.playbooksDisableEnvValue) - } else { - os.Unsetenv("MM_DISABLE_PLAYBOOKS") - } - if th.IncludeCacheLayer { // Clean all the caches th.App.Srv().InvalidateAllCaches() diff --git a/server/channels/web/web_test.go b/server/channels/web/web_test.go index 704c2dd0c7..a4458d39f1 100644 --- a/server/channels/web/web_test.go +++ b/server/channels/web/web_test.go @@ -48,9 +48,6 @@ type TestHelper struct { IncludeCacheLayer bool TestLogger *mlog.Logger - - boardsProductEnvValue string - playbooksDisableEnvValue string } func SetupWithStoreMock(tb testing.TB) *TestHelper { @@ -80,17 +77,6 @@ func setupTestHelper(tb testing.TB, includeCacheLayer bool) *TestHelper { *newConfig.AnnouncementSettings.AdminNoticesEnabled = false *newConfig.AnnouncementSettings.UserNoticesEnabled = false *newConfig.PluginSettings.AutomaticPrepackagedPlugins = false - - // disable Boards through the feature flag - boardsProductEnvValue := os.Getenv("MM_FEATUREFLAGS_BoardsProduct") - os.Unsetenv("MM_FEATUREFLAGS_BoardsProduct") - newConfig.FeatureFlags.BoardsProduct = false - - // disable Playbooks (temporarily) as it causes many more mocked methods to get - // called, and cannot receieve a mocked database. - playbooksDisableEnvValue := os.Getenv("MM_DISABLE_PLAYBOOKS") - os.Setenv("MM_DISABLE_PLAYBOOKS", "true") - memoryStore.Set(newConfig) var options []app.Option options = append(options, app.ConfigStore(memoryStore)) @@ -148,14 +134,12 @@ func setupTestHelper(tb testing.TB, includeCacheLayer bool) *TestHelper { }) th := &TestHelper{ - App: a, - Context: request.EmptyContext(testLogger), - Server: s, - Web: web, - IncludeCacheLayer: includeCacheLayer, - TestLogger: testLogger, - boardsProductEnvValue: boardsProductEnvValue, - playbooksDisableEnvValue: playbooksDisableEnvValue, + App: a, + Context: request.EmptyContext(testLogger), + Server: s, + Web: web, + IncludeCacheLayer: includeCacheLayer, + TestLogger: testLogger, } th.Context.SetLogger(testLogger) @@ -194,17 +178,6 @@ func (th *TestHelper) InitBasic() *TestHelper { } func (th *TestHelper) TearDown() { - // reset board and playbooks product setting to original - if th.boardsProductEnvValue != "" { - os.Setenv("MM_FEATUREFLAGS_BoardsProduct", th.boardsProductEnvValue) - } - - if th.playbooksDisableEnvValue != "" { - os.Setenv("MM_DISABLE_PLAYBOOKS", th.playbooksDisableEnvValue) - } else { - os.Unsetenv("MM_DISABLE_PLAYBOOKS") - } - if th.IncludeCacheLayer { // Clean all the caches th.App.Srv().InvalidateAllCaches() diff --git a/server/playbooks/server/api_actions_test.go b/server/playbooks/server/api_actions_test.go index 10672f9308..26ba51d31b 100644 --- a/server/playbooks/server/api_actions_test.go +++ b/server/playbooks/server/api_actions_test.go @@ -15,8 +15,7 @@ import ( ) func TestActionCreation(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() createNewChannel := func(t *testing.T, name string) *model.Channel { @@ -201,8 +200,7 @@ func TestActionCreation(t *testing.T) { } func TestActionList(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() // Create three valid actions @@ -294,8 +292,7 @@ func TestActionList(t *testing.T) { } func TestActionUpdate(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() // Create a valid action diff --git a/server/playbooks/server/api_bot_test.go b/server/playbooks/server/api_bot_test.go index e5ff029bfa..4ab0bd0196 100644 --- a/server/playbooks/server/api_bot_test.go +++ b/server/playbooks/server/api_bot_test.go @@ -16,8 +16,7 @@ func TestTrialLicences(t *testing.T) { // This test is flaky due to upstream connectivity issues. t.Skip() - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() t.Run("request trial license without permissions", func(t *testing.T) { diff --git a/server/playbooks/server/api_general_test.go b/server/playbooks/server/api_general_test.go index 380959325e..b3052eb649 100644 --- a/server/playbooks/server/api_general_test.go +++ b/server/playbooks/server/api_general_test.go @@ -11,8 +11,7 @@ import ( ) func TestAPI(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateClients() t.Run("404", func(t *testing.T) { diff --git a/server/playbooks/server/api_graphql_playbooks_test.go b/server/playbooks/server/api_graphql_playbooks_test.go index 8212c3dd8b..bcb78c08a3 100644 --- a/server/playbooks/server/api_graphql_playbooks_test.go +++ b/server/playbooks/server/api_graphql_playbooks_test.go @@ -21,8 +21,7 @@ import ( ) func TestGraphQLPlaybooks(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() t.Run("basic get", func(t *testing.T) { @@ -206,8 +205,7 @@ func TestGraphQLPlaybooks(t *testing.T) { } func TestGraphQLUpdatePlaybookFails(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() t.Run("update playbook fails because size constraints.", func(t *testing.T) { @@ -370,8 +368,7 @@ func TestGraphQLUpdatePlaybookFails(t *testing.T) { } func TestUpdatePlaybookFavorite(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() t.Run("favorite", func(t *testing.T) { @@ -493,8 +490,7 @@ func gqlTestPlaybookUpdate(e *TestEnvironment, t *testing.T, playbookID string, } func TestGraphQLPlaybooksMetrics(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() t.Run("metrics get", func(t *testing.T) { diff --git a/server/playbooks/server/api_graphql_runs_test.go b/server/playbooks/server/api_graphql_runs_test.go index 92897393b9..7a97b3be53 100644 --- a/server/playbooks/server/api_graphql_runs_test.go +++ b/server/playbooks/server/api_graphql_runs_test.go @@ -20,8 +20,7 @@ import ( ) func TestGraphQLRunList(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() t.Run("list by participantOrFollower", func(t *testing.T) { @@ -206,8 +205,7 @@ func TestGraphQLRunList(t *testing.T) { } func TestGraphQLChangeRunParticipants(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() user3, _, err := e.ServerAdminClient.CreateUser(&model.User{ @@ -669,8 +667,7 @@ func TestGraphQLChangeRunParticipants(t *testing.T) { } func TestGraphQLChangeRunOwner(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() // create a third user to test change owner @@ -713,8 +710,7 @@ func TestGraphQLChangeRunOwner(t *testing.T) { } func TestSetRunFavorite(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() createRun := func() *client.PlaybookRun { @@ -800,8 +796,7 @@ func TestSetRunFavorite(t *testing.T) { } func TestResolverFavorites(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() createRun := func() *client.PlaybookRun { @@ -833,8 +828,7 @@ func TestResolverFavorites(t *testing.T) { } func TestResolverPlaybooks(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() createRun := func() *client.PlaybookRun { @@ -860,8 +854,7 @@ func TestResolverPlaybooks(t *testing.T) { } func TestUpdateRun(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() createRun := func() *client.PlaybookRun { @@ -977,8 +970,7 @@ func TestUpdateRun(t *testing.T) { } func TestUpdateRunTaskActions(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() t.Run("task actions mutation create and update", func(t *testing.T) { @@ -1071,8 +1063,7 @@ func TestUpdateRunTaskActions(t *testing.T) { } func TestBadGraphQLRequest(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() testRunsQuery := ` diff --git a/server/playbooks/server/api_playbooks_test.go b/server/playbooks/server/api_playbooks_test.go index 67f70fe8b2..d1c9e8ebed 100644 --- a/server/playbooks/server/api_playbooks_test.go +++ b/server/playbooks/server/api_playbooks_test.go @@ -22,8 +22,7 @@ import ( ) func TestPlaybooks(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateClients() e.CreateBasicServer() @@ -267,8 +266,7 @@ func TestPlaybooks(t *testing.T) { } func TestCreateInvalidPlaybook(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateClients() e.CreateBasicServer() @@ -369,8 +367,7 @@ func TestCreateInvalidPlaybook(t *testing.T) { } func TestPlaybooksRetrieval(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() t.Run("get playbook", func(t *testing.T) { @@ -387,8 +384,7 @@ func TestPlaybooksRetrieval(t *testing.T) { } func TestPlaybookUpdate(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() t.Run("update playbook properties", func(t *testing.T) { @@ -521,8 +517,7 @@ func TestPlaybookUpdate(t *testing.T) { } func TestPlaybookUpdateCrossTeam(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() t.Run("update playbook properties not in team public playbook", func(t *testing.T) { @@ -552,8 +547,7 @@ func TestPlaybookUpdateCrossTeam(t *testing.T) { } func TestPlaybooksSort(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateClients() e.CreateBasicServer() e.SetE20Licence() @@ -795,8 +789,7 @@ func TestPlaybooksSort(t *testing.T) { } func TestPlaybooksPaging(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateClients() e.CreateBasicServer() e.SetE20Licence() @@ -935,8 +928,7 @@ func getPlaybookIDsList(playbooks []client.Playbook) []string { } func TestPlaybooksPermissions(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() t.Run("test no permissions to create", func(t *testing.T) { @@ -1148,8 +1140,7 @@ func TestPlaybooksPermissions(t *testing.T) { } func TestPlaybooksConversions(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() t.Run("public to private conversion", func(t *testing.T) { @@ -1208,8 +1199,7 @@ func TestPlaybooksConversions(t *testing.T) { } func TestPlaybooksImportExport(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateClients() e.CreateBasicServer() e.CreateBasicPublicPlaybook() @@ -1237,8 +1227,7 @@ func TestPlaybooksImportExport(t *testing.T) { } func TestPlaybooksDuplicate(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateClients() e.CreateBasicServer() e.SetE20Licence() @@ -1259,8 +1248,7 @@ func TestPlaybooksDuplicate(t *testing.T) { } func TestAddPostToTimeline(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() dialogRequest := model.SubmitDialogRequest{ @@ -1307,8 +1295,7 @@ func TestAddPostToTimeline(t *testing.T) { } func TestPlaybookStats(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateClients() e.CreateBasicServer() e.SetE20Licence() @@ -1343,8 +1330,7 @@ func TestPlaybookStats(t *testing.T) { } func TestPlaybookGetAutoFollows(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() p1ID, err := e.PlaybooksAdminClient.Playbooks.Create(context.Background(), client.PlaybookCreateOptions{ @@ -1450,8 +1436,7 @@ func TestPlaybookGetAutoFollows(t *testing.T) { } func TestPlaybookChecklistCleanup(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() t.Run("update playbook", func(t *testing.T) { diff --git a/server/playbooks/server/api_runs_test.go b/server/playbooks/server/api_runs_test.go index 780c0f8bb8..2cac09e2b3 100644 --- a/server/playbooks/server/api_runs_test.go +++ b/server/playbooks/server/api_runs_test.go @@ -19,8 +19,7 @@ import ( ) func TestRunCreation(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() incompletePlaybookID, err := e.PlaybooksAdminClient.Playbooks.Create(context.Background(), client.PlaybookCreateOptions{ @@ -314,8 +313,7 @@ func TestRunCreation(t *testing.T) { } func TestCreateRunInExistingChannel(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() // create playbook @@ -410,8 +408,7 @@ func TestCreateRunInExistingChannel(t *testing.T) { } func TestCreateInvalidRuns(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() t.Run("fails if description is longer than 4096", func(t *testing.T) { @@ -428,8 +425,7 @@ func TestCreateInvalidRuns(t *testing.T) { } func TestRunRetrieval(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() t.Run("by channel id", func(t *testing.T) { @@ -510,8 +506,7 @@ func TestRunRetrieval(t *testing.T) { } func TestRunPostStatusUpdate(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() t.Run("post an update", func(t *testing.T) { @@ -571,8 +566,7 @@ func TestRunPostStatusUpdate(t *testing.T) { } func TestChecklistManagement(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() createNewRunWithNoChecklists := func(t *testing.T) *client.PlaybookRun { @@ -1188,8 +1182,7 @@ func TestChecklistManagement(t *testing.T) { } func TestChecklisFailTooLarge(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() t.Run("checklist creation - failure: too large checklist", func(t *testing.T) { @@ -1213,8 +1206,7 @@ func TestChecklisFailTooLarge(t *testing.T) { } func TestRunGetStatusUpdates(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() t.Run("public - get no updates", func(t *testing.T) { @@ -1343,8 +1335,7 @@ func TestRunGetStatusUpdates(t *testing.T) { } func TestRequestUpdate(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() t.Run("private - no viewer access ", func(t *testing.T) { @@ -1437,8 +1428,7 @@ func TestRequestUpdate(t *testing.T) { } func TestReminderReset(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() t.Run("reminder reset - timeline event created", func(t *testing.T) { @@ -1485,8 +1475,7 @@ func TestReminderReset(t *testing.T) { } func TestChecklisItem_SetAssignee(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() addSimpleChecklistToTun := func(t *testing.T, runID string) *client.PlaybookRun { @@ -1597,8 +1586,7 @@ func TestChecklisItem_SetAssignee(t *testing.T) { } func TestChecklisItem_SetCommand(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() run, err := e.PlaybooksClient.PlaybookRuns.Create(context.Background(), client.PlaybookRunCreateOptions{ @@ -1699,8 +1687,7 @@ func TestChecklisItem_SetCommand(t *testing.T) { } func TestGetOwners(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() ownerFromUser := func(u *model.User) client.OwnerInfo { diff --git a/server/playbooks/server/api_settings_test.go b/server/playbooks/server/api_settings_test.go index c768866469..4ef06b42c4 100644 --- a/server/playbooks/server/api_settings_test.go +++ b/server/playbooks/server/api_settings_test.go @@ -14,8 +14,7 @@ import ( ) func TestSettings(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() t.Run("get settings", func(t *testing.T) { diff --git a/server/playbooks/server/api_stats_test.go b/server/playbooks/server/api_stats_test.go index 068c8979a6..a005ca7212 100644 --- a/server/playbooks/server/api_stats_test.go +++ b/server/playbooks/server/api_stats_test.go @@ -16,8 +16,7 @@ import ( ) func TestGetSiteStats(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() t.Run("get sites stats", func(t *testing.T) { @@ -50,8 +49,7 @@ func TestGetSiteStats(t *testing.T) { } func TestPlaybookKeyMetricsStats(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() t.Run("3 runs with published metrics, 2 runs without publishing", func(t *testing.T) { diff --git a/server/playbooks/server/api_telemetry_test.go b/server/playbooks/server/api_telemetry_test.go index ad7cfb11e9..7a3c9ab10f 100644 --- a/server/playbooks/server/api_telemetry_test.go +++ b/server/playbooks/server/api_telemetry_test.go @@ -11,8 +11,7 @@ import ( ) func TestCreateEvent(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() t.Run("create an event with bad type fails", func(t *testing.T) { diff --git a/server/playbooks/server/main_test.go b/server/playbooks/server/main_test.go index e41d6be5e1..c63f5e8b00 100644 --- a/server/playbooks/server/main_test.go +++ b/server/playbooks/server/main_test.go @@ -97,7 +97,7 @@ func getEnvWithDefault(name, defaultValue string) string { return defaultValue } -func Setup(t *testing.T) (*TestEnvironment, func()) { +func Setup(t *testing.T) *TestEnvironment { // Ignore any locally defined SiteURL as we intend to host our own. os.Unsetenv("MM_SERVICESETTINGS_SITEURL") os.Unsetenv("MM_SERVICESETTINGS_LISTENADDRESS") @@ -126,11 +126,6 @@ func Setup(t *testing.T) (*TestEnvironment, func()) { config.LogSettings.EnableFile = model.NewBool(false) config.LogSettings.ConsoleLevel = model.NewString("INFO") - // disable Boards through the feature flag - boardsProductEnvValue := os.Getenv("MM_FEATUREFLAGS_BoardsProduct") - os.Unsetenv("MM_FEATUREFLAGS_BoardsProduct") - config.FeatureFlags.BoardsProduct = false - // override config with e2etest.config.json if it exists textConfig, err := os.ReadFile("./e2etest.config.json") if err == nil { @@ -169,10 +164,6 @@ func Setup(t *testing.T) (*TestEnvironment, func()) { ap := sapp.New(sapp.ServerConnector(server.Channels())) - teardown := func() { - os.Setenv("MM_FEATUREFLAGS_BoardsProduct", boardsProductEnvValue) - } - return &TestEnvironment{ T: t, Srv: server, @@ -184,7 +175,7 @@ func Setup(t *testing.T) (*TestEnvironment, func()) { }, }, logger: testLogger, - }, teardown + } } func (e *TestEnvironment) CreateClients() { @@ -478,8 +469,7 @@ func (e *TestEnvironment) CreateBasic() { // TestTestFramework If this is failing you know the break is not exclusively in your test. func TestTestFramework(t *testing.T) { - e, teardown := Setup(t) - defer teardown() + e := Setup(t) e.CreateBasic() } From e755ae8635f1f647e391ae5f89192a03cdeb179b Mon Sep 17 00:00:00 2001 From: Jesse Hallam Date: Mon, 27 Mar 2023 13:19:58 -0300 Subject: [PATCH 23/46] Adopt placeholder_ semantics for telemetry key (#22621) Update playbooks to use the `placeholder_*` semantics in use by channels in boards. While debugging this, I realized the telemetry service isn't available until after `Start()` is called, so move most of the Playbooks initialization logic there. --- server/playbooks/product/playbooks_product.go | 453 +++++++++--------- 1 file changed, 227 insertions(+), 226 deletions(-) diff --git a/server/playbooks/product/playbooks_product.go b/server/playbooks/product/playbooks_product.go index e6b468741b..77360db7cd 100644 --- a/server/playbooks/product/playbooks_product.go +++ b/server/playbooks/product/playbooks_product.go @@ -7,6 +7,7 @@ import ( "fmt" "net/http" "os" + "strings" "time" "github.com/mattermost/mattermost-server/v6/model" @@ -53,12 +54,10 @@ const ( const ServerKey product.ServiceKey = "server" -// These credentials for Rudder need to be populated at build-time, -// passing the following flags to the go build command: -// -ldflags "-X main.rudderDataplaneURL= -X main.rudderWriteKey=" -var ( - rudderDataplaneURL string - rudderWriteKey string +// These credentials for Rudder need to be replaced at build-time. +const ( + rudderDataplaneURL = "placeholder_rudder_dataplane_url" + rudderWriteKey = "placeholder_playbooks_rudder_key" ) var errServiceTypeAssert = errors.New("type assertion failed") @@ -157,229 +156,9 @@ func newPlaybooksProduct(services map[product.ServiceKey]interface{}) (product.P return nil, err } - logger := logrus.StandardLogger() - ConfigureLogrus(logger, playbooks.logger) - playbooks.server = services[ServerKey].(*mmapp.Server) playbooks.serviceAdapter = newServiceAPIAdapter(playbooks) - botID, err := playbooks.serviceAdapter.EnsureBot(&model.Bot{ - Username: "playbooks", - DisplayName: "Playbooks", - Description: "Playbooks bot.", - OwnerId: "playbooks", - }) - if err != nil { - return nil, errors.Wrapf(err, "failed to ensure bot") - } - - playbooks.config = config.NewConfigService(playbooks.serviceAdapter) - err = playbooks.config.UpdateConfiguration(func(c *config.Configuration) { - c.BotUserID = botID - c.AdminLogLevel = "debug" - }) - if err != nil { - return nil, errors.Wrapf(err, "failed save bot to config") - } - - playbooks.handler = api.NewHandler(playbooks.config) - - if rudderDataplaneURL == "" || rudderWriteKey == "" { - logrus.Warn("Rudder credentials are not set. Disabling analytics.") - playbooks.telemetryClient = &telemetry.NoopTelemetry{} - } else { - diagnosticID := playbooks.serviceAdapter.GetDiagnosticID() - serverVersion := playbooks.serviceAdapter.GetServerVersion() - playbooks.telemetryClient, err = telemetry.NewRudder(rudderDataplaneURL, rudderWriteKey, diagnosticID, model.BuildHashPlaybooks, serverVersion) - if err != nil { - return nil, errors.Wrapf(err, "failed init telemetry client") - } - } - - toggleTelemetry := func() { - diagnosticsFlag := playbooks.serviceAdapter.GetConfig().LogSettings.EnableDiagnostics - telemetryEnabled := diagnosticsFlag != nil && *diagnosticsFlag - - if telemetryEnabled { - if err = playbooks.telemetryClient.Enable(); err != nil { - logrus.WithError(err).Error("Telemetry could not be enabled") - } - return - } - - if err = playbooks.telemetryClient.Disable(); err != nil { - logrus.WithError(err).Error("Telemetry could not be disabled") - } - } - - toggleTelemetry() - playbooks.config.RegisterConfigChangeListener(toggleTelemetry) - - apiClient := sqlstore.NewClient(playbooks.serviceAdapter) - playbooks.bot = bot.New(playbooks.serviceAdapter, playbooks.config.GetConfiguration().BotUserID, playbooks.config, playbooks.telemetryClient) - scheduler := cluster.GetJobOnceScheduler(playbooks.serviceAdapter) - - sqlStore, err := sqlstore.New(apiClient, scheduler) - if err != nil { - return nil, errors.Wrapf(err, "failed creating the SQL store") - } - - playbooks.playbookRunStore = sqlstore.NewPlaybookRunStore(apiClient, sqlStore) - playbooks.playbookStore = sqlstore.NewPlaybookStore(apiClient, sqlStore) - statsStore := sqlstore.NewStatsStore(apiClient, sqlStore) - playbooks.userInfoStore = sqlstore.NewUserInfoStore(sqlStore) - channelActionStore := sqlstore.NewChannelActionStore(apiClient, sqlStore) - categoryStore := sqlstore.NewCategoryStore(apiClient, sqlStore) - - playbooks.handler = api.NewHandler(playbooks.config) - - playbooks.playbookService = app.NewPlaybookService(playbooks.playbookStore, playbooks.bot, playbooks.telemetryClient, playbooks.serviceAdapter, playbooks.metricsService) - - keywordsThreadIgnorer := app.NewKeywordsThreadIgnorer() - playbooks.channelActionService = app.NewChannelActionsService(playbooks.serviceAdapter, playbooks.bot, playbooks.config, channelActionStore, playbooks.playbookService, keywordsThreadIgnorer, playbooks.telemetryClient) - playbooks.categoryService = app.NewCategoryService(categoryStore, playbooks.serviceAdapter, playbooks.telemetryClient) - - playbooks.licenseChecker = enterprise.NewLicenseChecker(playbooks.serviceAdapter) - - playbooks.playbookRunService = app.NewPlaybookRunService( - playbooks.playbookRunStore, - playbooks.bot, - playbooks.config, - scheduler, - playbooks.telemetryClient, - playbooks.telemetryClient, - playbooks.serviceAdapter, - playbooks.playbookService, - playbooks.channelActionService, - playbooks.licenseChecker, - playbooks.metricsService, - ) - - if err = scheduler.SetCallback(playbooks.playbookRunService.HandleReminder); err != nil { - logrus.WithError(err).Error("JobOnceScheduler could not add the playbookRunService's HandleReminder") - } - if err = scheduler.Start(); err != nil { - logrus.WithError(err).Error("JobOnceScheduler could not start") - } - - // Migrations use the scheduler, so they have to be run after playbookRunService and scheduler have started - mutex, err := cluster.NewMutex(playbooks.serviceAdapter, "IR_dbMutex") - if err != nil { - return nil, errors.Wrapf(err, "failed creating cluster mutex") - } - mutex.Lock() - if err = sqlStore.RunMigrations(); err != nil { - mutex.Unlock() - return nil, errors.Wrapf(err, "failed to run migrations") - } - mutex.Unlock() - - playbooks.permissions = app.NewPermissionsService( - playbooks.playbookService, - playbooks.playbookRunService, - playbooks.serviceAdapter, - playbooks.config, - playbooks.licenseChecker, - ) - - // register collections and topics. - // TODO bump the minimum server version - if err = playbooks.serviceAdapter.RegisterCollectionAndTopic(CollectionTypeRun, TopicTypeStatus); err != nil { - logrus.WithError(err).WithField("collection_type", CollectionTypeRun).WithField("topic_type", TopicTypeStatus).Warnf("failed to register collection and topic") - } - if err = playbooks.serviceAdapter.RegisterCollectionAndTopic(CollectionTypeRun, TopicTypeTask); err != nil { - logrus.WithError(err).WithField("collection_type", CollectionTypeRun).WithField("topic_type", TopicTypeTask).Warnf("failed to register collection and topic") - } - - api.NewGraphQLHandler( - playbooks.handler.APIRouter, - playbooks.playbookService, - playbooks.playbookRunService, - playbooks.categoryService, - playbooks.serviceAdapter, - playbooks.config, - playbooks.permissions, - playbooks.playbookStore, - playbooks.licenseChecker, - ) - api.NewPlaybookHandler( - playbooks.handler.APIRouter, - playbooks.playbookService, - playbooks.serviceAdapter, - playbooks.config, - playbooks.permissions, - ) - api.NewPlaybookRunHandler( - playbooks.handler.APIRouter, - playbooks.playbookRunService, - playbooks.playbookService, - playbooks.permissions, - playbooks.licenseChecker, - playbooks.serviceAdapter, - playbooks.bot, - playbooks.config, - ) - api.NewStatsHandler( - playbooks.handler.APIRouter, - playbooks.serviceAdapter, - statsStore, - playbooks.playbookService, - playbooks.permissions, - playbooks.licenseChecker, - ) - api.NewBotHandler( - playbooks.handler.APIRouter, - playbooks.serviceAdapter, playbooks.bot, - playbooks.config, - playbooks.playbookRunService, - playbooks.userInfoStore, - ) - api.NewTelemetryHandler( - playbooks.handler.APIRouter, - playbooks.playbookRunService, - playbooks.serviceAdapter, - playbooks.telemetryClient, - playbooks.playbookService, - playbooks.telemetryClient, - playbooks.telemetryClient, - playbooks.telemetryClient, - playbooks.permissions, - ) - api.NewSignalHandler( - playbooks.handler.APIRouter, - playbooks.serviceAdapter, - playbooks.playbookRunService, - playbooks.playbookService, - keywordsThreadIgnorer, - ) - api.NewSettingsHandler( - playbooks.handler.APIRouter, - playbooks.serviceAdapter, - playbooks.config, - ) - api.NewActionsHandler( - playbooks.handler.APIRouter, - playbooks.channelActionService, - playbooks.serviceAdapter, - playbooks.permissions, - ) - api.NewCategoryHandler( - playbooks.handler.APIRouter, - playbooks.serviceAdapter, - playbooks.categoryService, - playbooks.playbookService, - playbooks.playbookRunService, - ) - - isTestingEnabled := false - flag := playbooks.serviceAdapter.GetConfig().ServiceSettings.EnableTesting - if flag != nil { - isTestingEnabled = *flag - } - - if err = command.RegisterCommands(playbooks.serviceAdapter.RegisterCommand, isTestingEnabled); err != nil { - return nil, errors.Wrapf(err, "failed register commands") - } return playbooks, nil } @@ -531,6 +310,228 @@ func (pp *playbooksProduct) setProductServices(services map[product.ServiceKey]i } func (pp *playbooksProduct) Start() error { + logger := logrus.StandardLogger() + ConfigureLogrus(logger, pp.logger) + + botID, err := pp.serviceAdapter.EnsureBot(&model.Bot{ + Username: "playbooks", + DisplayName: "Playbooks", + Description: "Playbooks bot.", + OwnerId: "playbooks", + }) + if err != nil { + return errors.Wrapf(err, "failed to ensure bot") + } + + pp.config = config.NewConfigService(pp.serviceAdapter) + err = pp.config.UpdateConfiguration(func(c *config.Configuration) { + c.BotUserID = botID + c.AdminLogLevel = "debug" + }) + if err != nil { + return errors.Wrapf(err, "failed save bot to config") + } + + pp.handler = api.NewHandler(pp.config) + + if strings.HasPrefix(rudderWriteKey, "placeholder_") { + logrus.Warn("Rudder credentials are not set. Disabling analytics.") + pp.telemetryClient = &telemetry.NoopTelemetry{} + } else { + logrus.Info("Rudder credentials are set. Enabling analytics.") + diagnosticID := pp.serviceAdapter.GetDiagnosticID() + serverVersion := pp.serviceAdapter.GetServerVersion() + pp.telemetryClient, err = telemetry.NewRudder(rudderDataplaneURL, rudderWriteKey, diagnosticID, model.BuildHashPlaybooks, serverVersion) + if err != nil { + return errors.Wrapf(err, "failed init telemetry client") + } + } + + toggleTelemetry := func() { + diagnosticsFlag := pp.serviceAdapter.GetConfig().LogSettings.EnableDiagnostics + telemetryEnabled := diagnosticsFlag != nil && *diagnosticsFlag + + if telemetryEnabled { + if err = pp.telemetryClient.Enable(); err != nil { + logrus.WithError(err).Error("Telemetry could not be enabled") + } + return + } + + if err = pp.telemetryClient.Disable(); err != nil { + logrus.WithError(err).Error("Telemetry could not be disabled") + } + } + + toggleTelemetry() + pp.config.RegisterConfigChangeListener(toggleTelemetry) + + apiClient := sqlstore.NewClient(pp.serviceAdapter) + pp.bot = bot.New(pp.serviceAdapter, pp.config.GetConfiguration().BotUserID, pp.config, pp.telemetryClient) + scheduler := cluster.GetJobOnceScheduler(pp.serviceAdapter) + + sqlStore, err := sqlstore.New(apiClient, scheduler) + if err != nil { + return errors.Wrapf(err, "failed creating the SQL store") + } + + pp.playbookRunStore = sqlstore.NewPlaybookRunStore(apiClient, sqlStore) + pp.playbookStore = sqlstore.NewPlaybookStore(apiClient, sqlStore) + statsStore := sqlstore.NewStatsStore(apiClient, sqlStore) + pp.userInfoStore = sqlstore.NewUserInfoStore(sqlStore) + channelActionStore := sqlstore.NewChannelActionStore(apiClient, sqlStore) + categoryStore := sqlstore.NewCategoryStore(apiClient, sqlStore) + + pp.handler = api.NewHandler(pp.config) + + pp.playbookService = app.NewPlaybookService(pp.playbookStore, pp.bot, pp.telemetryClient, pp.serviceAdapter, pp.metricsService) + + keywordsThreadIgnorer := app.NewKeywordsThreadIgnorer() + pp.channelActionService = app.NewChannelActionsService(pp.serviceAdapter, pp.bot, pp.config, channelActionStore, pp.playbookService, keywordsThreadIgnorer, pp.telemetryClient) + pp.categoryService = app.NewCategoryService(categoryStore, pp.serviceAdapter, pp.telemetryClient) + + pp.licenseChecker = enterprise.NewLicenseChecker(pp.serviceAdapter) + + pp.playbookRunService = app.NewPlaybookRunService( + pp.playbookRunStore, + pp.bot, + pp.config, + scheduler, + pp.telemetryClient, + pp.telemetryClient, + pp.serviceAdapter, + pp.playbookService, + pp.channelActionService, + pp.licenseChecker, + pp.metricsService, + ) + + if err = scheduler.SetCallback(pp.playbookRunService.HandleReminder); err != nil { + logrus.WithError(err).Error("JobOnceScheduler could not add the playbookRunService's HandleReminder") + } + if err = scheduler.Start(); err != nil { + logrus.WithError(err).Error("JobOnceScheduler could not start") + } + + // Migrations use the scheduler, so they have to be run after playbookRunService and scheduler have started + mutex, err := cluster.NewMutex(pp.serviceAdapter, "IR_dbMutex") + if err != nil { + return errors.Wrapf(err, "failed creating cluster mutex") + } + mutex.Lock() + if err = sqlStore.RunMigrations(); err != nil { + mutex.Unlock() + return errors.Wrapf(err, "failed to run migrations") + } + mutex.Unlock() + + pp.permissions = app.NewPermissionsService( + pp.playbookService, + pp.playbookRunService, + pp.serviceAdapter, + pp.config, + pp.licenseChecker, + ) + + // register collections and topics. + // TODO bump the minimum server version + if err = pp.serviceAdapter.RegisterCollectionAndTopic(CollectionTypeRun, TopicTypeStatus); err != nil { + logrus.WithError(err).WithField("collection_type", CollectionTypeRun).WithField("topic_type", TopicTypeStatus).Warnf("failed to register collection and topic") + } + if err = pp.serviceAdapter.RegisterCollectionAndTopic(CollectionTypeRun, TopicTypeTask); err != nil { + logrus.WithError(err).WithField("collection_type", CollectionTypeRun).WithField("topic_type", TopicTypeTask).Warnf("failed to register collection and topic") + } + + api.NewGraphQLHandler( + pp.handler.APIRouter, + pp.playbookService, + pp.playbookRunService, + pp.categoryService, + pp.serviceAdapter, + pp.config, + pp.permissions, + pp.playbookStore, + pp.licenseChecker, + ) + api.NewPlaybookHandler( + pp.handler.APIRouter, + pp.playbookService, + pp.serviceAdapter, + pp.config, + pp.permissions, + ) + api.NewPlaybookRunHandler( + pp.handler.APIRouter, + pp.playbookRunService, + pp.playbookService, + pp.permissions, + pp.licenseChecker, + pp.serviceAdapter, + pp.bot, + pp.config, + ) + api.NewStatsHandler( + pp.handler.APIRouter, + pp.serviceAdapter, + statsStore, + pp.playbookService, + pp.permissions, + pp.licenseChecker, + ) + api.NewBotHandler( + pp.handler.APIRouter, + pp.serviceAdapter, pp.bot, + pp.config, + pp.playbookRunService, + pp.userInfoStore, + ) + api.NewTelemetryHandler( + pp.handler.APIRouter, + pp.playbookRunService, + pp.serviceAdapter, + pp.telemetryClient, + pp.playbookService, + pp.telemetryClient, + pp.telemetryClient, + pp.telemetryClient, + pp.permissions, + ) + api.NewSignalHandler( + pp.handler.APIRouter, + pp.serviceAdapter, + pp.playbookRunService, + pp.playbookService, + keywordsThreadIgnorer, + ) + api.NewSettingsHandler( + pp.handler.APIRouter, + pp.serviceAdapter, + pp.config, + ) + api.NewActionsHandler( + pp.handler.APIRouter, + pp.channelActionService, + pp.serviceAdapter, + pp.permissions, + ) + api.NewCategoryHandler( + pp.handler.APIRouter, + pp.serviceAdapter, + pp.categoryService, + pp.playbookService, + pp.playbookRunService, + ) + + isTestingEnabled := false + flag := pp.serviceAdapter.GetConfig().ServiceSettings.EnableTesting + if flag != nil { + isTestingEnabled = *flag + } + + if err = command.RegisterCommands(pp.serviceAdapter.RegisterCommand, isTestingEnabled); err != nil { + return errors.Wrapf(err, "failed register commands") + } + if err := pp.hooksService.RegisterHooks(playbooksProductName, pp); err != nil { return fmt.Errorf("failed to register hooks: %w", err) } From 1cf0cff9c6056f1d57d3042b2341005b6d9c28a7 Mon Sep 17 00:00:00 2001 From: Jesse Hallam Date: Mon, 27 Mar 2023 13:20:39 -0300 Subject: [PATCH 24/46] Boards: Use custom placeholder for telemetry. (#22623) Adopt `placeholder_boards_rudder_key` as the replacement value for injecting the telemetry key, allowing Boards to preserve its unique telemetry key. Co-authored-by: Mattermost Build --- server/boards/services/telemetry/telemetry.go | 2 +- webapp/boards/src/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/boards/services/telemetry/telemetry.go b/server/boards/services/telemetry/telemetry.go index 61b40247a9..9719f76f78 100644 --- a/server/boards/services/telemetry/telemetry.go +++ b/server/boards/services/telemetry/telemetry.go @@ -17,7 +17,7 @@ import ( ) const ( - rudderKey = "placeholder_rudder_key" + rudderKey = "placeholder_boards_rudder_key" rudderDataplaneURL = "placeholder_rudder_dataplane_url" timeBetweenTelemetryChecks = 10 * time.Minute ) diff --git a/webapp/boards/src/index.tsx b/webapp/boards/src/index.tsx index 6413dd486d..3e807e1b5a 100644 --- a/webapp/boards/src/index.tsx +++ b/webapp/boards/src/index.tsx @@ -85,7 +85,7 @@ function getSubpath(siteURL: string): string { return url.pathname.replace(/\/+$/, '') } -const TELEMETRY_RUDDER_KEY = 'placeholder_rudder_key' +const TELEMETRY_RUDDER_KEY = 'placeholder_boards_rudder_key' const TELEMETRY_RUDDER_DATAPLANE_URL = 'placeholder_rudder_dataplane_url' const TELEMETRY_OPTIONS = { context: { From 50a9b9bdfafc527374dafb023b18b021d3e20e9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20Mondrag=C3=B3n?= <79058848+julmondragon@users.noreply.github.com> Date: Mon, 27 Mar 2023 12:54:30 -0500 Subject: [PATCH 25/46] MM-50976_Fix error on non-cloud initial start (#22692) --- webapp/channels/src/components/common/hooks/useOpenSalesLink.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/channels/src/components/common/hooks/useOpenSalesLink.ts b/webapp/channels/src/components/common/hooks/useOpenSalesLink.ts index 4dbe44d0ca..1bc2c87e31 100644 --- a/webapp/channels/src/components/common/hooks/useOpenSalesLink.ts +++ b/webapp/channels/src/components/common/hooks/useOpenSalesLink.ts @@ -26,7 +26,7 @@ export default function useOpenSalesLink(): [() => void, string] { companyName = customer.name || ''; utmMedium = 'in-product-cloud'; } else { - customerEmail = currentUser.email || ''; + customerEmail = currentUser?.email || ''; } const contactSalesLink = buildMMURL(LicenseLinks.CONTACT_SALES, firstName, lastName, companyName, customerEmail, utmSource, utmMedium); From 0140e94d77b1c7ee646a857ae1958b29bbea318e Mon Sep 17 00:00:00 2001 From: Allan Guwatudde Date: Mon, 27 Mar 2023 22:38:19 +0300 Subject: [PATCH 26/46] [MM-49751] - Turn off Inactive Server Email (#22648) * [MM-49751] - Turn off Inactive Server Email * remove unused var --------- Co-authored-by: Mattermost Build --- model/config.go | 5 - model/feature_flags.go | 3 - server/channels/app/email/email.go | 46 -- server/channels/app/email/email_test.go | 1 - .../app/email/mocks/ServiceInterface.go | 14 - server/channels/app/email/service.go | 1 - server/channels/app/server.go | 7 - server/channels/app/server_inactivity.go | 119 ---- .../opentracinglayer/opentracinglayer.go | 36 -- .../channels/store/retrylayer/retrylayer.go | 42 -- server/channels/store/sqlstore/post_store.go | 11 - .../channels/store/sqlstore/session_store.go | 11 - server/channels/store/store.go | 2 - .../store/storetest/mocks/PostStore.go | 21 - .../store/storetest/mocks/SessionStore.go | 21 - server/channels/store/storetest/post_store.go | 35 -- .../channels/store/storetest/session_store.go | 18 - .../channels/store/timerlayer/timerlayer.go | 32 - server/i18n/en.json | 48 -- .../platform/services/telemetry/telemetry.go | 1 - server/templates/inactivity_body.html | 548 ------------------ server/templates/inactivity_body.mjml | 65 --- server/tests/test-config.json | 1 - 23 files changed, 1088 deletions(-) delete mode 100644 server/channels/app/server_inactivity.go delete mode 100644 server/templates/inactivity_body.html delete mode 100644 server/templates/inactivity_body.mjml diff --git a/model/config.go b/model/config.go index b5272d5f1f..3e0f60c8c7 100644 --- a/model/config.go +++ b/model/config.go @@ -1624,7 +1624,6 @@ type EmailSettings struct { LoginButtonColor *string `access:"experimental_features"` LoginButtonBorderColor *string `access:"experimental_features"` LoginButtonTextColor *string `access:"experimental_features"` - EnableInactivityEmail *bool } func (s *EmailSettings) SetDefaults(isUpdate bool) { @@ -1767,10 +1766,6 @@ func (s *EmailSettings) SetDefaults(isUpdate bool) { if s.LoginButtonTextColor == nil { s.LoginButtonTextColor = NewString("#2389D7") } - - if s.EnableInactivityEmail == nil { - s.EnableInactivityEmail = NewBool(true) - } } type RateLimitSettings struct { diff --git a/model/feature_flags.go b/model/feature_flags.go index 86bb298e5b..ebe357d3d9 100644 --- a/model/feature_flags.go +++ b/model/feature_flags.go @@ -41,8 +41,6 @@ type FeatureFlags struct { NormalizeLdapDNs bool - EnableInactivityCheckJob bool - // Enable special onboarding flow for first admin UseCaseOnboarding bool @@ -92,7 +90,6 @@ func (f *FeatureFlags) SetDefaults() { f.BoardsFeatureFlags = "" f.BoardsDataRetention = false f.NormalizeLdapDNs = false - f.EnableInactivityCheckJob = true f.UseCaseOnboarding = true f.GraphQL = false f.InsightsEnabled = true diff --git a/server/channels/app/email/email.go b/server/channels/app/email/email.go index 4444f42e5d..bb64e6efd0 100644 --- a/server/channels/app/email/email.go +++ b/server/channels/app/email/email.go @@ -11,8 +11,6 @@ import ( "io" "net/http" "net/url" - "os" - "strconv" "strings" "github.com/pkg/errors" @@ -26,8 +24,6 @@ import ( "github.com/microcosm-cc/bluemonday" ) -const serverInactivityHours = 100 - // Returns category if enabled is true (default false) // If "" is returned when enabled is false, the category headers aren't attached to the email func getSendGridCategory(category string, enabled bool) string { @@ -948,48 +944,6 @@ func (es *Service) CreateVerifyEmailToken(userID string, newEmail string) (*mode return token, nil } -func (es *Service) SendLicenseInactivityEmail(email, name, locale, siteURL string) error { - T := i18n.GetUserTranslations(locale) - subject := T("api.templates.server_inactivity_subject") - data := es.NewEmailTemplateData(locale) - data.Props["SiteURL"] = siteURL - data.Props["Title"] = T("api.templates.server_inactivity_title") - data.Props["SubTitle"] = T("api.templates.server_inactivity_subtitle", map[string]any{"Name": name}) - data.Props["InfoBullet"] = T("api.templates.server_inactivity_info_bullet") - data.Props["InfoBullet1"] = T("api.templates.server_inactivity_info_bullet1") - data.Props["InfoBullet2"] = T("api.templates.server_inactivity_info_bullet2") - data.Props["Info"] = T("api.templates.server_inactivity_info") - data.Props["EmailUs"] = T("api.templates.email_us_anytime_at") - data.Props["QuestionTitle"] = T("api.templates.questions_footer.title") - data.Props["QuestionInfo"] = T("api.templates.questions_footer.info") - data.Props["Button"] = T("api.templates.server_inactivity_button") - data.Props["SupportEmail"] = "feedback@mattermost.com" - data.Props["ButtonURL"] = siteURL - data.Props["Channels"] = T("Channels") - data.Props["Playbooks"] = T("Playbooks") - data.Props["Boards"] = T("Boards") - - inactivityDurationHoursEnv := os.Getenv("MM_INACTIVITY_DURATION") - inactivityDurationHours, parseError := strconv.ParseFloat(inactivityDurationHoursEnv, 64) - if parseError != nil { - // default to 100 hours - inactivityDurationHours = serverInactivityHours - } - - data.Props["FooterDisclaimer"] = T("api.templates.server_inactivity_footer_disclaimer", map[string]any{"Hours": inactivityDurationHours}) - - body, err := es.templatesContainer.RenderToString("inactivity_body", data) - if err != nil { - return err - } - - if err := es.sendMail(email, subject, body, "LicenseInactivityEmail"); err != nil { - return err - } - - return nil -} - func (es *Service) SendLicenseUpForRenewalEmail(email, name, locale, siteURL, ctaTitle, ctaLink, ctaText string, daysToExpiration int) error { T := i18n.GetUserTranslations(locale) subject := T("api.templates.license_up_for_renewal_subject") diff --git a/server/channels/app/email/email_test.go b/server/channels/app/email/email_test.go index d8b22431fc..3fb2e09a7a 100644 --- a/server/channels/app/email/email_test.go +++ b/server/channels/app/email/email_test.go @@ -408,7 +408,6 @@ func TestMailServiceConfig(t *testing.T) { LoginButtonColor: new(string), LoginButtonBorderColor: new(string), LoginButtonTextColor: new(string), - EnableInactivityEmail: new(bool), }, } }, diff --git a/server/channels/app/email/mocks/ServiceInterface.go b/server/channels/app/email/mocks/ServiceInterface.go index b86365846a..e4d4011f45 100644 --- a/server/channels/app/email/mocks/ServiceInterface.go +++ b/server/channels/app/email/mocks/ServiceInterface.go @@ -344,20 +344,6 @@ func (_m *ServiceInterface) SendInviteEmailsToTeamAndChannels(team *model.Team, return r0, r1 } -// SendLicenseInactivityEmail provides a mock function with given fields: _a0, name, locale, siteURL -func (_m *ServiceInterface) SendLicenseInactivityEmail(_a0 string, name string, locale string, siteURL string) error { - ret := _m.Called(_a0, name, locale, siteURL) - - var r0 error - if rf, ok := ret.Get(0).(func(string, string, string, string) error); ok { - r0 = rf(_a0, name, locale, siteURL) - } else { - r0 = ret.Error(0) - } - - return r0 -} - // SendLicenseUpForRenewalEmail provides a mock function with given fields: _a0, name, locale, siteURL, ctaTitle, ctaLink, ctaText, daysToExpiration func (_m *ServiceInterface) SendLicenseUpForRenewalEmail(_a0 string, name string, locale string, siteURL string, ctaTitle string, ctaLink string, ctaText string, daysToExpiration int) error { ret := _m.Called(_a0, name, locale, siteURL, ctaTitle, ctaLink, ctaText, daysToExpiration) diff --git a/server/channels/app/email/service.go b/server/channels/app/email/service.go index f5f186c168..3aa0b658f4 100644 --- a/server/channels/app/email/service.go +++ b/server/channels/app/email/service.go @@ -163,7 +163,6 @@ type ServiceInterface interface { InitEmailBatching() SendChangeUsernameEmail(newUsername, email, locale, siteURL string) error CreateVerifyEmailToken(userID string, newEmail string) (*model.Token, error) - SendLicenseInactivityEmail(email, name, locale, siteURL string) error Stop() } diff --git a/server/channels/app/server.go b/server/channels/app/server.go index c416089792..6197c6c55b 100644 --- a/server/channels/app/server.go +++ b/server/channels/app/server.go @@ -484,7 +484,6 @@ func NewServer(options ...Option) (*Server, error) { s.Go(func() { appInstance := New(ServerConnector(s.Channels())) s.runLicenseExpirationCheckJob() - s.runInactivityCheckJob() runDNDStatusExpireJob(appInstance) runPostReminderJob(appInstance) }) @@ -1198,12 +1197,6 @@ func runConfigCleanupJob(s *Server) { }, time.Hour*24) } -func (s *Server) runInactivityCheckJob() { - model.CreateRecurringTask("Server inactivity Check", func() { - s.doInactivityCheck() - }, time.Hour*24) -} - func (s *Server) runLicenseExpirationCheckJob() { s.doLicenseExpirationCheck() model.CreateRecurringTask("License Expiration Check", func() { diff --git a/server/channels/app/server_inactivity.go b/server/channels/app/server_inactivity.go deleted file mode 100644 index a1693069fb..0000000000 --- a/server/channels/app/server_inactivity.go +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -package app - -import ( - "os" - "strconv" - "time" - - "github.com/mattermost/mattermost-server/v6/model" - "github.com/mattermost/mattermost-server/v6/server/platform/shared/mlog" -) - -const serverInactivityHours = 100 -const inactivityEmailSent = "INACTIVITY" - -func (s *Server) doInactivityCheck() { - - if *s.platform.Config().ServiceSettings.EnableDeveloper { - mlog.Info("No activity check because developer mode is enabled") - return - } - - if !*s.platform.Config().EmailSettings.EnableInactivityEmail { - mlog.Info("No activity check because EnableInactivityEmail is false") - return - } - - if !s.platform.Config().FeatureFlags.EnableInactivityCheckJob { - mlog.Info("No activity check because EnableInactivityCheckJob feature flag is disabled") - return - } - - _, sysValErr := s.Store().System().GetByName(inactivityEmailSent) - // if there is no error which may include *store.ErrNotFound, it means this check was already flagged as done - if sysValErr == nil { - return - } - - inactivityDurationHoursEnv := os.Getenv("MM_INACTIVITY_DURATION") - inactivityDurationHours, parseError := strconv.ParseFloat(inactivityDurationHoursEnv, 64) - if parseError != nil { - // default to 100 hours - inactivityDurationHours = serverInactivityHours - } - - // The first time this job runs. We check if the user has not made any posts in last inactivityDurationHours - // and remind them to use the workspace. If no posts have been made. We check the last time - // they logged in (session) for the last inactivityDurationHours and send a reminder. - lastPostAt, _ := s.Store().Post().GetLastPostRowCreateAt() - if lastPostAt != 0 { - posT := time.Unix(lastPostAt/1000, 0) - timeForLastPost := time.Since(posT).Hours() - if timeForLastPost > inactivityDurationHours { - s.takeInactivityAction() - } - return - } - - lastSessionAt, _ := s.Store().Session().GetLastSessionRowCreateAt() - if lastSessionAt != 0 { - sesT := time.Unix(lastSessionAt/1000, 0) - timeForLastSession := time.Since(sesT).Hours() - if timeForLastSession > inactivityDurationHours { - s.takeInactivityAction() - } - return - } -} - -func (s *Server) takeInactivityAction() { - siteURL := *s.platform.Config().ServiceSettings.SiteURL - if siteURL == "" { - mlog.Warn("No SiteURL configured") - } - - properties := map[string]any{ - "SiteURL": siteURL, - } - s.GetTelemetryService().SendTelemetry("inactive_server", properties) - users, err := s.Store().User().GetSystemAdminProfiles() - if err != nil { - mlog.Error("Failed to get system admins for inactivity check from Mattermost.") - return - } - - for _, user := range users { - - // See https://go.dev/doc/faq#closures_and_goroutines for why we make this assignment - user := user - - if user.Email == "" { - mlog.Error("Invalid system admin email.", mlog.String("user_email", user.Email)) - continue - } - - name := user.FirstName - if name == "" { - name = user.Username - } - - mlog.Debug("Sending inactivity reminder email.", mlog.String("user_email", user.Email)) - s.Go(func() { - if err := s.EmailService.SendLicenseInactivityEmail(user.Email, name, user.Locale, siteURL); err != nil { - mlog.Error("Error while sending inactivity reminder email.", mlog.String("user_email", user.Email), mlog.Err(err)) - } - }) - } - - // Mark that we sent emails. - sysVar := &model.System{Name: inactivityEmailSent, Value: "true"} - if err := s.Store().System().SaveOrUpdate(sysVar); err != nil { - mlog.Error("Unable to save INACTIVITY", mlog.Err(err)) - } - - // do some telemetry about sending the email - s.GetTelemetryService().SendTelemetry("inactive_server_emails_sent", properties) -} diff --git a/server/channels/store/opentracinglayer/opentracinglayer.go b/server/channels/store/opentracinglayer/opentracinglayer.go index 1f7d408365..15d32a18e2 100644 --- a/server/channels/store/opentracinglayer/opentracinglayer.go +++ b/server/channels/store/opentracinglayer/opentracinglayer.go @@ -6057,24 +6057,6 @@ func (s *OpenTracingLayerPostStore) GetFlaggedPostsForTeam(userID string, teamID return result, err } -func (s *OpenTracingLayerPostStore) GetLastPostRowCreateAt() (int64, error) { - origCtx := s.Root.Store.Context() - span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "PostStore.GetLastPostRowCreateAt") - s.Root.Store.SetContext(newCtx) - defer func() { - s.Root.Store.SetContext(origCtx) - }() - - defer span.Finish() - result, err := s.PostStore.GetLastPostRowCreateAt() - if err != nil { - span.LogFields(spanlog.Error(err)) - ext.Error.Set(span, true) - } - - return result, err -} - func (s *OpenTracingLayerPostStore) GetMaxPostSize() int { origCtx := s.Root.Store.Context() span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "PostStore.GetMaxPostSize") @@ -8171,24 +8153,6 @@ func (s *OpenTracingLayerSessionStore) Get(ctx context.Context, sessionIDOrToken return result, err } -func (s *OpenTracingLayerSessionStore) GetLastSessionRowCreateAt() (int64, error) { - origCtx := s.Root.Store.Context() - span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "SessionStore.GetLastSessionRowCreateAt") - s.Root.Store.SetContext(newCtx) - defer func() { - s.Root.Store.SetContext(origCtx) - }() - - defer span.Finish() - result, err := s.SessionStore.GetLastSessionRowCreateAt() - if err != nil { - span.LogFields(spanlog.Error(err)) - ext.Error.Set(span, true) - } - - return result, err -} - func (s *OpenTracingLayerSessionStore) GetSessions(userID string) ([]*model.Session, error) { origCtx := s.Root.Store.Context() span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "SessionStore.GetSessions") diff --git a/server/channels/store/retrylayer/retrylayer.go b/server/channels/store/retrylayer/retrylayer.go index 121a769248..07997b61ac 100644 --- a/server/channels/store/retrylayer/retrylayer.go +++ b/server/channels/store/retrylayer/retrylayer.go @@ -6856,27 +6856,6 @@ func (s *RetryLayerPostStore) GetFlaggedPostsForTeam(userID string, teamID strin } -func (s *RetryLayerPostStore) GetLastPostRowCreateAt() (int64, error) { - - tries := 0 - for { - result, err := s.PostStore.GetLastPostRowCreateAt() - if err == nil { - return result, nil - } - if !isRepeatableError(err) { - return result, err - } - tries++ - if tries >= 3 { - err = errors.Wrap(err, "giving up after 3 consecutive repeatable transaction failures") - return result, err - } - timepkg.Sleep(100 * timepkg.Millisecond) - } - -} - func (s *RetryLayerPostStore) GetMaxPostSize() int { return s.PostStore.GetMaxPostSize() @@ -9304,27 +9283,6 @@ func (s *RetryLayerSessionStore) Get(ctx context.Context, sessionIDOrToken strin } -func (s *RetryLayerSessionStore) GetLastSessionRowCreateAt() (int64, error) { - - tries := 0 - for { - result, err := s.SessionStore.GetLastSessionRowCreateAt() - if err == nil { - return result, nil - } - if !isRepeatableError(err) { - return result, err - } - tries++ - if tries >= 3 { - err = errors.Wrap(err, "giving up after 3 consecutive repeatable transaction failures") - return result, err - } - timepkg.Sleep(100 * timepkg.Millisecond) - } - -} - func (s *RetryLayerSessionStore) GetSessions(userID string) ([]*model.Session, error) { tries := 0 diff --git a/server/channels/store/sqlstore/post_store.go b/server/channels/store/sqlstore/post_store.go index c07c51a3cd..85854fdb90 100644 --- a/server/channels/store/sqlstore/post_store.go +++ b/server/channels/store/sqlstore/post_store.go @@ -2300,17 +2300,6 @@ func (s *SqlPostStore) AnalyticsPostCount(options *model.PostCountOptions) (int6 return v, nil } -func (s *SqlPostStore) GetLastPostRowCreateAt() (int64, error) { - query := `SELECT CREATEAT FROM Posts ORDER BY CREATEAT DESC LIMIT 1` - var createAt int64 - err := s.GetReplicaX().Get(&createAt, query) - if err != nil { - return 0, errors.Wrapf(err, "failed to get last post createat") - } - - return createAt, nil -} - func (s *SqlPostStore) GetPostsCreatedAt(channelId string, time int64) ([]*model.Post, error) { query := `SELECT * FROM Posts WHERE CreateAt = ? AND ChannelId = ?` diff --git a/server/channels/store/sqlstore/session_store.go b/server/channels/store/sqlstore/session_store.go index afe15e183e..851336dbc6 100644 --- a/server/channels/store/sqlstore/session_store.go +++ b/server/channels/store/sqlstore/session_store.go @@ -221,17 +221,6 @@ func (me SqlSessionStore) UpdateExpiresAt(sessionId string, time int64) error { return nil } -func (me *SqlSessionStore) GetLastSessionRowCreateAt() (int64, error) { - query := `SELECT CREATEAT FROM Sessions ORDER BY CREATEAT DESC LIMIT 1` - var createAt int64 - err := me.GetReplicaX().Get(&createAt, query) - if err != nil { - return 0, errors.Wrapf(err, "failed to get last session createat") - } - - return createAt, nil -} - func (me SqlSessionStore) UpdateLastActivityAt(sessionId string, time int64) error { _, err := me.GetMasterX().Exec("UPDATE Sessions SET LastActivityAt = ? WHERE Id = ?", time, sessionId) if err != nil { diff --git a/server/channels/store/store.go b/server/channels/store/store.go index 1ac231cb06..dec4fa0f89 100644 --- a/server/channels/store/store.go +++ b/server/channels/store/store.go @@ -381,7 +381,6 @@ type PostStore interface { AnalyticsPostCount(options *model.PostCountOptions) (int64, error) ClearCaches() InvalidateLastPostTimeCache(channelID string) - GetLastPostRowCreateAt() (int64, error) GetPostsCreatedAt(channelID string, timestamp int64) ([]*model.Post, error) Overwrite(post *model.Post) (*model.Post, error) OverwriteMultiple(posts []*model.Post) ([]*model.Post, int, error) @@ -510,7 +509,6 @@ type SessionStore interface { Remove(sessionIDOrToken string) error RemoveAllSessions() error PermanentDeleteSessionsByUser(teamID string) error - GetLastSessionRowCreateAt() (int64, error) UpdateExpiresAt(sessionID string, timestamp int64) error UpdateLastActivityAt(sessionID string, timestamp int64) error UpdateRoles(userID string, roles string) (string, error) diff --git a/server/channels/store/storetest/mocks/PostStore.go b/server/channels/store/storetest/mocks/PostStore.go index 3a57536e0f..727b5944dd 100644 --- a/server/channels/store/storetest/mocks/PostStore.go +++ b/server/channels/store/storetest/mocks/PostStore.go @@ -277,27 +277,6 @@ func (_m *PostStore) GetFlaggedPostsForTeam(userID string, teamID string, offset return r0, r1 } -// GetLastPostRowCreateAt provides a mock function with given fields: -func (_m *PostStore) GetLastPostRowCreateAt() (int64, error) { - ret := _m.Called() - - var r0 int64 - if rf, ok := ret.Get(0).(func() int64); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(int64) - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - // GetMaxPostSize provides a mock function with given fields: func (_m *PostStore) GetMaxPostSize() int { ret := _m.Called() diff --git a/server/channels/store/storetest/mocks/SessionStore.go b/server/channels/store/storetest/mocks/SessionStore.go index 7d5be8a3fb..eea72a1d4e 100644 --- a/server/channels/store/storetest/mocks/SessionStore.go +++ b/server/channels/store/storetest/mocks/SessionStore.go @@ -74,27 +74,6 @@ func (_m *SessionStore) Get(ctx context.Context, sessionIDOrToken string) (*mode return r0, r1 } -// GetLastSessionRowCreateAt provides a mock function with given fields: -func (_m *SessionStore) GetLastSessionRowCreateAt() (int64, error) { - ret := _m.Called() - - var r0 int64 - if rf, ok := ret.Get(0).(func() int64); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(int64) - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - // GetSessions provides a mock function with given fields: userID func (_m *SessionStore) GetSessions(userID string) ([]*model.Session, error) { ret := _m.Called(userID) diff --git a/server/channels/store/storetest/post_store.go b/server/channels/store/storetest/post_store.go index a47e096386..a718eb76ac 100644 --- a/server/channels/store/storetest/post_store.go +++ b/server/channels/store/storetest/post_store.go @@ -43,7 +43,6 @@ func TestPostStore(t *testing.T, ss store.Store, s SqlStore) { t.Run("GetFlaggedPosts", func(t *testing.T) { testPostStoreGetFlaggedPosts(t, ss) }) t.Run("GetFlaggedPostsForChannel", func(t *testing.T) { testPostStoreGetFlaggedPostsForChannel(t, ss) }) t.Run("GetPostsCreatedAt", func(t *testing.T) { testPostStoreGetPostsCreatedAt(t, ss) }) - t.Run("GetLastPostRowCreateAt", func(t *testing.T) { testPostStoreGetLastPostRowCreateAt(t, ss) }) t.Run("Overwrite", func(t *testing.T) { testPostStoreOverwrite(t, ss) }) t.Run("OverwriteMultiple", func(t *testing.T) { testPostStoreOverwriteMultiple(t, ss) }) t.Run("GetPostsByIds", func(t *testing.T) { testPostStoreGetPostsByIds(t, ss) }) @@ -3361,40 +3360,6 @@ func testPostStoreGetFlaggedPostsForChannel(t *testing.T, ss store.Store) { require.Len(t, r.Order, 0, "should have 0 posts") } -func testPostStoreGetLastPostRowCreateAt(t *testing.T, ss store.Store) { - teamId := model.NewId() - channel1, err := ss.Channel().Save(&model.Channel{ - TeamId: teamId, - DisplayName: "DisplayName1", - Name: "channel" + model.NewId(), - Type: model.ChannelTypeOpen, - }, -1) - require.NoError(t, err) - - createTime1 := model.GetMillis() + 1 - o0 := &model.Post{} - o0.ChannelId = channel1.Id - o0.UserId = model.NewId() - o0.Message = NewTestId() - o0.CreateAt = createTime1 - o0, err = ss.Post().Save(o0) - require.NoError(t, err) - - createTime2 := model.GetMillis() + 2 - - o1 := &model.Post{} - o1.ChannelId = o0.ChannelId - o1.UserId = model.NewId() - o1.Message = "Latest message" - o1.CreateAt = createTime2 - _, err = ss.Post().Save(o1) - require.NoError(t, err) - - createAt, err := ss.Post().GetLastPostRowCreateAt() - require.NoError(t, err) - assert.Equal(t, createAt, createTime2) -} - func testPostStoreGetPostsCreatedAt(t *testing.T, ss store.Store) { teamId := model.NewId() channel1, err := ss.Channel().Save(&model.Channel{ diff --git a/server/channels/store/storetest/session_store.go b/server/channels/store/storetest/session_store.go index fa3156979a..3c8fba5504 100644 --- a/server/channels/store/storetest/session_store.go +++ b/server/channels/store/storetest/session_store.go @@ -33,7 +33,6 @@ func TestSessionStore(t *testing.T, ss store.Store) { t.Run("SessionUpdateDeviceId2", func(t *testing.T) { testSessionUpdateDeviceId2(t, ss) }) t.Run("UpdateExpiresAt", func(t *testing.T) { testSessionStoreUpdateExpiresAt(t, ss) }) t.Run("UpdateLastActivityAt", func(t *testing.T) { testSessionStoreUpdateLastActivityAt(t, ss) }) - t.Run("GetLastSessionRowCreateAt", func(t *testing.T) { testSessionStoreGetLastSessionRowCreateAt(t, ss) }) t.Run("SessionCount", func(t *testing.T) { testSessionCount(t, ss) }) t.Run("GetSessionsExpired", func(t *testing.T) { testGetSessionsExpired(t, ss) }) t.Run("UpdateExpiredNotify", func(t *testing.T) { testUpdateExpiredNotify(t, ss) }) @@ -47,23 +46,6 @@ func testSessionStoreSave(t *testing.T, ss store.Store) { require.NoError(t, err) } -func testSessionStoreGetLastSessionRowCreateAt(t *testing.T, ss store.Store) { - s1 := &model.Session{} - s1.UserId = model.NewId() - _, err := ss.Session().Save(s1) - require.NoError(t, err) - - latestSessionUserid := model.NewId() - s2 := &model.Session{} - s2.UserId = latestSessionUserid - latestSession, err := ss.Session().Save(s2) - require.NoError(t, err) - - createAt, err := ss.Session().GetLastSessionRowCreateAt() - require.NoError(t, err) - assert.Equal(t, latestSession.CreateAt, createAt) -} - func testSessionGet(t *testing.T, ss store.Store) { s1 := &model.Session{} s1.UserId = model.NewId() diff --git a/server/channels/store/timerlayer/timerlayer.go b/server/channels/store/timerlayer/timerlayer.go index 219154d479..8199138ac2 100644 --- a/server/channels/store/timerlayer/timerlayer.go +++ b/server/channels/store/timerlayer/timerlayer.go @@ -5483,22 +5483,6 @@ func (s *TimerLayerPostStore) GetFlaggedPostsForTeam(userID string, teamID strin return result, err } -func (s *TimerLayerPostStore) GetLastPostRowCreateAt() (int64, error) { - start := time.Now() - - result, err := s.PostStore.GetLastPostRowCreateAt() - - elapsed := float64(time.Since(start)) / float64(time.Second) - if s.Root.Metrics != nil { - success := "false" - if err == nil { - success = "true" - } - s.Root.Metrics.ObserveStoreMethodDuration("PostStore.GetLastPostRowCreateAt", success, elapsed) - } - return result, err -} - func (s *TimerLayerPostStore) GetMaxPostSize() int { start := time.Now() @@ -7370,22 +7354,6 @@ func (s *TimerLayerSessionStore) Get(ctx context.Context, sessionIDOrToken strin return result, err } -func (s *TimerLayerSessionStore) GetLastSessionRowCreateAt() (int64, error) { - start := time.Now() - - result, err := s.SessionStore.GetLastSessionRowCreateAt() - - elapsed := float64(time.Since(start)) / float64(time.Second) - if s.Root.Metrics != nil { - success := "false" - if err == nil { - success = "true" - } - s.Root.Metrics.ObserveStoreMethodDuration("SessionStore.GetLastSessionRowCreateAt", success, elapsed) - } - return result, err -} - func (s *TimerLayerSessionStore) GetSessions(userID string) ([]*model.Session, error) { start := time.Now() diff --git a/server/i18n/en.json b/server/i18n/en.json index 07b6d2219b..ded7d5c8a6 100644 --- a/server/i18n/en.json +++ b/server/i18n/en.json @@ -7,14 +7,6 @@ "id": "August", "translation": "August" }, - { - "id": "Boards", - "translation": "Boards" - }, - { - "id": "Channels", - "translation": "Channels" - }, { "id": "December", "translation": "December" @@ -51,10 +43,6 @@ "id": "October", "translation": "October" }, - { - "id": "Playbooks", - "translation": "Playbooks" - }, { "id": "September", "translation": "September" @@ -3763,42 +3751,6 @@ "id": "api.templates.reset_subject", "translation": "[{{ .SiteName }}] Reset your password" }, - { - "id": "api.templates.server_inactivity_button", - "translation": "Open Mattermost" - }, - { - "id": "api.templates.server_inactivity_footer_disclaimer", - "translation": "You received this one-time email because your Mattermost server was inactive for more than {{.Hours}} hours. This email was automatically generated by your Mattermost server." - }, - { - "id": "api.templates.server_inactivity_info", - "translation": "Come and check it out!" - }, - { - "id": "api.templates.server_inactivity_info_bullet", - "translation": "Guest Access to specified " - }, - { - "id": "api.templates.server_inactivity_info_bullet1", - "translation": "Workflow management with " - }, - { - "id": "api.templates.server_inactivity_info_bullet2", - "translation": "Manage tasks using " - }, - { - "id": "api.templates.server_inactivity_subject", - "translation": "Come open Mattermost to increase your team’s productivity!" - }, - { - "id": "api.templates.server_inactivity_subtitle", - "translation": "Hey {{.Name}}, we’ve noticed that your Mattermost server is collecting a bit of dust. Take a look at some features that can help lighten your team's workload." - }, - { - "id": "api.templates.server_inactivity_title", - "translation": "Unlock increased productivity with these awesome features" - }, { "id": "api.templates.signin_change_email.body.info", "translation": "You updated your sign-in method on {{ .SiteName }} to {{.Method}}." diff --git a/server/platform/services/telemetry/telemetry.go b/server/platform/services/telemetry/telemetry.go index cf3402a8c1..a214911f20 100644 --- a/server/platform/services/telemetry/telemetry.go +++ b/server/platform/services/telemetry/telemetry.go @@ -609,7 +609,6 @@ func (ts *TelemetryService) trackConfig() { "isdefault_login_button_border_color": isDefault(*cfg.EmailSettings.LoginButtonBorderColor, ""), "isdefault_login_button_text_color": isDefault(*cfg.EmailSettings.LoginButtonTextColor, ""), "smtp_server_timeout": *cfg.EmailSettings.SMTPServerTimeout, - "enable_inactivity_email": *cfg.EmailSettings.EnableInactivityEmail, }) ts.SendTelemetry(TrackConfigRate, map[string]any{ diff --git a/server/templates/inactivity_body.html b/server/templates/inactivity_body.html deleted file mode 100644 index 36bb7795cb..0000000000 --- a/server/templates/inactivity_body.html +++ /dev/null @@ -1,548 +0,0 @@ -{{define "inactivity_body"}} - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - -
- -
- - - - - - -
- -
- - - - - - -
- - - - - - -
- -
-
-
- -
-
- -
- - - - - - -
- -
- - - - - - - - - - - - - - - - - - -
-
{{.Props.Title}}
-
-
{{.Props.SubTitle}}
-
-
-
    -
  • {{.Props.InfoBullet}}{{.Props.Channels}}
  • -
  • {{.Props.InfoBullet1}}{{.Props.Playbooks}}
  • -
  • {{.Props.InfoBullet2}}{{.Props.Boards}}
  • -
-
-
-
{{.Props.Info}}
-
- - - - -
- - {{.Props.Button}} - -
-
-
- -
-
- -
- - - - - - -
- -
- - - - - - -
- - - - - - -
- -
-
-
- -
-
- -
- - - - - - -
- -
- - - - - - - - - -
-
{{.Props.QuestionTitle}}
-
-
{{.Props.QuestionInfo}} - - {{.Props.SupportEmail}} - -
-
-
- -
-
- -
- - - - - - -
- -
- - - - - - - - - -
-
{{.Props.FooterDisclaimer}}
-
-
{{.Props.Organization}} - {{.Props.FooterV2}} -
-
-
- -
-
- -
-
- -
- - - - -{{end}} diff --git a/server/templates/inactivity_body.mjml b/server/templates/inactivity_body.mjml deleted file mode 100644 index 47b17fe42c..0000000000 --- a/server/templates/inactivity_body.mjml +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - {{.Props.Title}} - - - {{.Props.SubTitle}} - - -
    -
  • {{.Props.InfoBullet}}{{.Props.Channels}}
  • -
  • {{.Props.InfoBullet1}}{{.Props.Playbooks}}
  • -
  • {{.Props.InfoBullet2}}{{.Props.Boards}}
  • -
-
- - {{.Props.Info}} - - {{.Props.Button}} -
-
- - - - - - - - - - - {{.Props.QuestionTitle}} - - - {{.Props.QuestionInfo}} - - {{.Props.SupportEmail}} - - - - - - - - - {{.Props.FooterDisclaimer}} - - - {{.Props.Organization}} - {{.Props.FooterV2}} - - - - -
-
-
diff --git a/server/tests/test-config.json b/server/tests/test-config.json index 3604556889..d98cbd98ca 100644 --- a/server/tests/test-config.json +++ b/server/tests/test-config.json @@ -167,7 +167,6 @@ "LoginButtonColor": "", "LoginButtonBorderColor": "", "LoginButtonTextColor": "", - "EnableInactivityEmail": true }, "RateLimitSettings": { "Enable": false, From ae6416e35749318f891fa041281cbd5e604508dd Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Mon, 27 Mar 2023 14:02:18 -0700 Subject: [PATCH 27/46] Remove configuration auto enable. (#22625) * Remove configuration auto enable. * i18n * Fix diff tests. --- model/config.go | 10 ---------- server/channels/api4/config.go | 5 ----- server/config/diff_test.go | 18 ------------------ server/i18n/en.json | 4 ---- 4 files changed, 37 deletions(-) diff --git a/model/config.go b/model/config.go index 3e0f60c8c7..6c5306950d 100644 --- a/model/config.go +++ b/model/config.go @@ -2867,21 +2867,11 @@ func (s *PluginSettings) SetDefaults(ls LogSettings) { s.PluginStates[PluginIdNPS] = &PluginState{Enable: ls.EnableDiagnostics == nil || *ls.EnableDiagnostics} } - if s.PluginStates[PluginIdPlaybooks] == nil { - // Enable the playbooks plugin by default - s.PluginStates[PluginIdPlaybooks] = &PluginState{Enable: true} - } - if s.PluginStates[PluginIdChannelExport] == nil && BuildEnterpriseReady == "true" { // Enable the channel export plugin by default s.PluginStates[PluginIdChannelExport] = &PluginState{Enable: true} } - if s.PluginStates[PluginIdFocalboard] == nil { - // Enable the focalboard plugin by default - s.PluginStates[PluginIdFocalboard] = &PluginState{Enable: true} - } - if s.PluginStates[PluginIdApps] == nil { // Enable the Apps plugin by default s.PluginStates[PluginIdApps] = &PluginState{Enable: true} diff --git a/server/channels/api4/config.go b/server/channels/api4/config.go index e1875e26bc..042636b17e 100644 --- a/server/channels/api4/config.go +++ b/server/channels/api4/config.go @@ -157,11 +157,6 @@ func updateConfig(c *Context, w http.ResponseWriter, r *http.Request) { *cfg.PluginSettings.MarketplaceURL = *appCfg.PluginSettings.MarketplaceURL } - if cfg.PluginSettings.PluginStates[model.PluginIdFocalboard].Enable && cfg.FeatureFlags.BoardsProduct { - c.Err = model.NewAppError("EnablePlugin", "app.plugin.product_mode.app_error", map[string]any{"Name": model.PluginIdFocalboard}, "", http.StatusInternalServerError) - return - } - // There are some settings that cannot be changed in a cloud env if c.App.Channels().License().IsCloud() { // Both of them cannot be nil since cfg.SetDefaults is called earlier for cfg, diff --git a/server/config/diff_test.go b/server/config/diff_test.go index 15ec6f41f7..bf1a79ab37 100644 --- a/server/config/diff_test.go +++ b/server/config/diff_test.go @@ -807,12 +807,6 @@ func TestDiff(t *testing.T) { "com.mattermost.nps": { Enable: !defaultConfigGen().PluginSettings.PluginStates["com.mattermost.nps"].Enable, }, - "focalboard": { - Enable: true, - }, - "playbooks": { - Enable: true, - }, "com.mattermost.apps": { Enable: true, }, @@ -845,12 +839,6 @@ func TestDiff(t *testing.T) { "com.mattermost.newplugin": { Enable: true, }, - "focalboard": { - Enable: true, - }, - "playbooks": { - Enable: true, - }, "com.mattermost.apps": { Enable: true, }, @@ -875,12 +863,6 @@ func TestDiff(t *testing.T) { Path: "PluginSettings.PluginStates", BaseVal: defaultConfigGen().PluginSettings.PluginStates, ActualVal: map[string]*model.PluginState{ - "focalboard": { - Enable: true, - }, - "playbooks": { - Enable: true, - }, "com.mattermost.apps": { Enable: true, }, diff --git a/server/i18n/en.json b/server/i18n/en.json index ded7d5c8a6..492fee9d58 100644 --- a/server/i18n/en.json +++ b/server/i18n/en.json @@ -6043,10 +6043,6 @@ "id": "app.plugin.not_installed.app_error", "translation": "Plugin is not installed." }, - { - "id": "app.plugin.product_mode.app_error", - "translation": "Plugin {{.Name}} cannot be enabled in product mode." - }, { "id": "app.plugin.remove.app_error", "translation": "Unable to delete plugin." From d0babfd254b02dfe8e7cfadf93644493c0de74f0 Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Mon, 27 Mar 2023 14:04:28 -0700 Subject: [PATCH 28/46] Remove unhelpful test publish. (#22633) --- .github/workflows/channels-ci.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/workflows/channels-ci.yml b/.github/workflows/channels-ci.yml index 781cc6dd57..5fee62d830 100644 --- a/.github/workflows/channels-ci.yml +++ b/.github/workflows/channels-ci.yml @@ -154,13 +154,6 @@ jobs: npm run test-ci --workspace=channels npm run test-ci --workspace=platform/client npm run test-ci --workspace=playbooks - - name: ci/publish-test-results - uses: EnricoMi/publish-unit-test-result-action@a3caf02865c0604ad3dc1ecfcc5cdec9c41b7936 # v2.3.0 - if: always() - with: - junit_files: "webapp/channels/build/**/*.xml" - comment_mode: always - compare_to_earlier_commit: false build: runs-on: ubuntu-22.04 defaults: From dc4e7bf2ec5e98cbc7e720199d6f42424183f78d Mon Sep 17 00:00:00 2001 From: Ashish Dhama Date: Tue, 28 Mar 2023 06:17:42 +0530 Subject: [PATCH 29/46] [MM-51680] : Revert New Browse Channels UI modal changes (https://github.com/mattermost/mattermost-webapp/pull/11262) (#22613) * Revert https://github.com/mattermost/mattermost-webapp/pull/11262 * fix missing translation * fix indentation issue * fix imports in Update accessibility_modals_dialogs_spec.js --------- Co-authored-by: Mattermost Build --- .../channel/archived_channels_1_spec.js | 16 +- .../channels/channel/more_channels_spec.js | 16 +- .../channel/more_public_channels_spec.js | 14 +- .../new_channel_dropdown_spec.ts | 6 +- .../accessibility_modals_dialogs_spec.js | 26 +- .../enterprise/ldap/ldap_group_sync_spec.js | 4 +- .../src/actions/channel_actions.test.ts | 2 +- .../channels/src/actions/channel_actions.ts | 6 +- .../searchable_channel_list.test.jsx.snap | 46 ++ .../magnifying_glass_svg.tsx | 39 -- .../src/components/generic_modal.scss | 1 - .../__snapshots__/more_channels.test.tsx.snap | 136 ++++- .../searchable_channel_list.test.jsx.snap | 82 --- .../src/components/more_channels/index.ts | 29 +- .../more_channels/more_channels.scss | 295 ----------- .../more_channels/more_channels.test.tsx | 55 +- .../more_channels/more_channels.tsx | 194 +++---- .../more_channels/searchable_channel_list.jsx | 483 ------------------ .../components/searchable_channel_list.jsx | 319 ++++++++++++ .../searchable_channel_list.test.jsx | 15 +- webapp/channels/src/i18n/en.json | 15 +- .../components/_channel-invite-modal.scss | 2 - webapp/channels/src/utils/constants.tsx | 1 - .../src/generic_modal/generic_modal.tsx | 2 - 24 files changed, 631 insertions(+), 1173 deletions(-) create mode 100644 webapp/channels/src/components/__snapshots__/searchable_channel_list.test.jsx.snap delete mode 100644 webapp/channels/src/components/common/svg_images_components/magnifying_glass_svg.tsx delete mode 100644 webapp/channels/src/components/more_channels/__snapshots__/searchable_channel_list.test.jsx.snap delete mode 100644 webapp/channels/src/components/more_channels/more_channels.scss delete mode 100644 webapp/channels/src/components/more_channels/searchable_channel_list.jsx create mode 100644 webapp/channels/src/components/searchable_channel_list.jsx rename webapp/channels/src/components/{more_channels => }/searchable_channel_list.test.jsx (70%) diff --git a/e2e/cypress/tests/integration/channels/channel/archived_channels_1_spec.js b/e2e/cypress/tests/integration/channels/channel/archived_channels_1_spec.js index f6f6a3e186..1880dafb8a 100644 --- a/e2e/cypress/tests/integration/channels/channel/archived_channels_1_spec.js +++ b/e2e/cypress/tests/integration/channels/channel/archived_channels_1_spec.js @@ -97,7 +97,7 @@ describe('Leave an archived channel', () => { // # More channels modal opens cy.get('#moreChannelsModal').should('be.visible').within(() => { // # Click on dropdown - cy.findByText('Channel Type: Public').should('be.visible').click(); + cy.findByText('Show: Public Channels').should('be.visible').click(); // # Click archived channels cy.findByText('Archived Channels').click(); @@ -143,9 +143,9 @@ describe('Leave an archived channel', () => { cy.get('#showMoreChannels').click(); // # More channels modal opens - cy.get('#moreChannelsModal').should('be.visible').within(() => { + cy.get('.more-modal').should('be.visible').within(() => { // # Public channel list opens by default - cy.findByText('Channel Type: Public').should('be.visible').click(); + cy.findByText('Show: Public Channels').should('be.visible').click(); // # Click on archived channels cy.findByText('Archived Channels').click(); @@ -196,9 +196,9 @@ describe('Leave an archived channel', () => { cy.get('#showMoreChannels').click(); // # More channels modal opens - cy.get('#moreChannelsModal').should('be.visible').within(() => { + cy.get('.more-modal').should('be.visible').within(() => { // # Public channels are shown by default - cy.findByText('Channel Type: Public').should('be.visible').click(); + cy.findByText('Show: Public Channels').should('be.visible').click(); // # Go to archived channels cy.findByText('Archived Channels').click(); @@ -250,9 +250,9 @@ describe('Leave an archived channel', () => { cy.get('#showMoreChannels').click(); // # More channels modal opens - cy.get('#moreChannelsModal').should('be.visible').within(() => { + cy.get('.more-modal').should('be.visible').within(() => { // # Show public channels is visible by default - cy.findByText('Channel Type: Public').should('be.visible').click(); + cy.findByText('Show: Public Channels').should('be.visible').click(); // # Go to archived channels cy.findByText('Archived Channels').click(); @@ -286,7 +286,7 @@ describe('Leave an archived channel', () => { // # More channels modal opens and lands on public channels cy.get('#moreChannelsModal').should('be.visible').within(() => { - cy.findByText('Channel Type: Public').should('be.visible').click(); + cy.findByText('Show: Public Channels').should('be.visible').click(); // # Go to archived channels cy.findByText('Archived Channels').click(); diff --git a/e2e/cypress/tests/integration/channels/channel/more_channels_spec.js b/e2e/cypress/tests/integration/channels/channel/more_channels_spec.js index 7848ae787c..d83797db07 100644 --- a/e2e/cypress/tests/integration/channels/channel/more_channels_spec.js +++ b/e2e/cypress/tests/integration/channels/channel/more_channels_spec.js @@ -65,7 +65,7 @@ describe('Channels', () => { cy.get('#moreChannelsModal').should('be.visible').within(() => { // * Dropdown should be visible, defaulting to "Public Channels" - cy.get('#channelsMoreDropdown').should('be.visible').and('contain', 'Channel Type: Public').wait(TIMEOUTS.HALF_SEC); + cy.get('#channelsMoreDropdown').should('be.visible').and('contain', 'Show: Public Channels').wait(TIMEOUTS.HALF_SEC); cy.get('#searchChannelsTextbox').should('be.visible').type(testChannel.display_name).wait(TIMEOUTS.HALF_SEC); cy.get('#moreChannelsList').should('be.visible').children().should('have.length', 1).within(() => { @@ -80,8 +80,8 @@ describe('Channels', () => { }); }); - // # Verify that the modal is not closed - cy.get('#moreChannelsModal').should('exist'); + // # Verify that the modal is closed and it's redirected to the selected channel + cy.get('#moreChannelsModal').should('not.exist'); cy.url().should('include', `/${testTeam.name}/channels/${testChannel.name}`); // # Login as channel admin and go directly to the channel @@ -113,7 +113,7 @@ describe('Channels', () => { cy.findByText('Archived Channels').should('be.visible').click(); // * Channel test should be visible as an archived channel in the list - cy.wrap(el).should('contain', 'Channel Type: Archived'); + cy.wrap(el).should('contain', 'Show: Archived Channels'); }); cy.get('#searchChannelsTextbox').should('be.visible').type(testChannel.display_name).wait(TIMEOUTS.HALF_SEC); @@ -196,7 +196,7 @@ describe('Channels', () => { // * Dropdown should be visible, defaulting to "Public Channels" cy.get('#channelsMoreDropdown').should('be.visible').within((el) => { - cy.wrap(el).should('contain', 'Channel Type: Public'); + cy.wrap(el).should('contain', 'Show: Public Channels'); }); // * Users should be able to type and search @@ -207,12 +207,12 @@ describe('Channels', () => { cy.get('#moreChannelsModal').should('be.visible').within(() => { // * Users should be able to switch to "Archived Channels" list - cy.get('#channelsMoreDropdown').should('be.visible').and('contain', 'Channel Type: Public').click().within((el) => { + cy.get('#channelsMoreDropdown').should('be.visible').and('contain', 'Show: Public Channels').click().within((el) => { // # Click on archived channels item cy.findByText('Archived Channels').should('be.visible').click(); // * Modal should show the archived channels list - cy.wrap(el).should('contain', 'Channel Type: Archived'); + cy.wrap(el).should('contain', 'Show: Archived Channels'); }).wait(TIMEOUTS.HALF_SEC); cy.get('#searchChannelsTextbox').clear(); cy.get('#moreChannelsList').should('be.visible').children().should('have.length', 2); @@ -250,7 +250,7 @@ function verifyMoreChannelsModal(isEnabled) { // * Verify that the more channels modal is open and with or without option to view archived channels cy.get('#moreChannelsModal').should('be.visible').within(() => { if (isEnabled) { - cy.get('#channelsMoreDropdown').should('be.visible').and('have.text', 'Channel Type: Public'); + cy.get('#channelsMoreDropdown').should('be.visible').and('have.text', 'Show: Public Channels'); } else { cy.get('#channelsMoreDropdown').should('not.exist'); } diff --git a/e2e/cypress/tests/integration/channels/channel/more_public_channels_spec.js b/e2e/cypress/tests/integration/channels/channel/more_public_channels_spec.js index 0d38de9467..5808654971 100644 --- a/e2e/cypress/tests/integration/channels/channel/more_public_channels_spec.js +++ b/e2e/cypress/tests/integration/channels/channel/more_public_channels_spec.js @@ -11,7 +11,8 @@ // Group: @channels @channel function verifyNoChannelToJoinMessage(isVisible) { - cy.findByText('No public channels').should(isVisible ? 'be.visible' : 'not.exist'); + cy.findByText('No more channels to join').should(isVisible ? 'be.visible' : 'not.exist'); + cy.findByText('Click \'Create New Channel\' to make a new one').should(isVisible ? 'be.visible' : 'not.exist'); } describe('more public channels', () => { @@ -52,10 +53,7 @@ describe('more public channels', () => { cy.uiBrowseOrCreateChannel('Browse Channels').click(); // * Assert that the moreChannelsModel is visible - cy.findByRole('dialog', {name: 'Browse Channels'}).should('be.visible').within(() => { - // # Click hide joined checkbox - cy.findByText('Hide Joined').should('be.visible').click(); - + cy.findByRole('dialog', {name: 'More Channels'}).should('be.visible').within(() => { // * Assert that the moreChannelsList is visible and the number of channels is 31 cy.get('#moreChannelsList').should('be.visible').children().should('have.length', 31); @@ -88,9 +86,9 @@ describe('more public channels', () => { cy.uiBrowseOrCreateChannel('Browse Channels').click(); // * Assert the moreChannelsModel is visible - cy.findByRole('dialog', {name: 'Browse Channels'}).should('be.visible').within(() => { - // # Click hide joined checkbox - cy.findByText('Hide Joined').should('be.visible').click(); + cy.findByRole('dialog', {name: 'More Channels'}).should('be.visible').within(() => { + // * Assert the moreChannelsList does have one child + cy.get('#moreChannelsList').should('be.visible').children().should('have.length', 1); // * Assert that the "No more channels to join" message is visible verifyNoChannelToJoinMessage(true); diff --git a/e2e/cypress/tests/integration/channels/channel_sidebar/new_channel_dropdown_spec.ts b/e2e/cypress/tests/integration/channels/channel_sidebar/new_channel_dropdown_spec.ts index b94d16acfa..17114e21aa 100644 --- a/e2e/cypress/tests/integration/channels/channel_sidebar/new_channel_dropdown_spec.ts +++ b/e2e/cypress/tests/integration/channels/channel_sidebar/new_channel_dropdown_spec.ts @@ -68,13 +68,13 @@ describe('Channel sidebar', () => { cy.get('.AddChannelDropdown .MenuItem:contains(Browse Channels) button').should('be.visible').click(); // * Verify that the more channels modal is visible - cy.get('#moreChannelsModal').should('be.visible'); + cy.get('.more-modal').should('be.visible'); // Click the Off-Topic channel - cy.findByText('Off-Topic').should('be.visible').click(); + cy.get('.more-modal button:contains(Off-Topic)').should('be.visible').click(); // Verify that new channel is in the sidebar and is active - cy.get('#moreChannelsModal').should('exist'); + cy.get('.more-modal').should('not.exist'); cy.url().should('include', `/${teamName}/channels/off-topic`); cy.get('#channelHeaderTitle').should('contain', 'Off-Topic'); cy.get('.SidebarChannel.active:contains(Off-Topic)').should('be.visible'); diff --git a/e2e/cypress/tests/integration/channels/enterprise/accessibility/accessibility_modals_dialogs_spec.js b/e2e/cypress/tests/integration/channels/enterprise/accessibility/accessibility_modals_dialogs_spec.js index adf5478b55..a068d15f9f 100644 --- a/e2e/cypress/tests/integration/channels/enterprise/accessibility/accessibility_modals_dialogs_spec.js +++ b/e2e/cypress/tests/integration/channels/enterprise/accessibility/accessibility_modals_dialogs_spec.js @@ -104,26 +104,30 @@ describe('Verify Accessibility Support in Modals & Dialogs', () => { cy.uiBrowseOrCreateChannel('Browse Channels').click(); // * Verify the accessibility support in More Channels Dialog - cy.findByRole('dialog', {name: 'Browse Channels'}).within(() => { - cy.findByRole('heading', {name: 'Browse Channels'}); + cy.findByRole('dialog', {name: 'More Channels'}).within(() => { + cy.findByRole('heading', {name: 'More Channels'}); // * Verify the accessibility support in search input cy.findByPlaceholderText('Search channels'); - cy.get('#moreChannelsList').should('be.visible').then((el) => { + cy.waitUntil(() => cy.get('#moreChannelsList').then((el) => { return el[0].children.length === 2; - }); + })); - // # Hide already joined channels - cy.findByText('Hide Joined').click(); - - // # Focus on the Create Channel button and TAB three time - cy.get('#createNewChannelButton').focus().tab().tab().tab(); + // # Focus on the Create Channel button and TAB twice + cy.get('#createNewChannel').focus().tab().tab(); // * Verify channel name is highlighted and reader reads the channel name and channel description - cy.get('#moreChannelsList').within(() => { + cy.get('#moreChannelsList').children().eq(0).within(() => { const selectedChannel = getChannelAriaLabel(channel); - cy.findByLabelText(selectedChannel).should('be.visible').should('be.focused'); + cy.findByLabelText(selectedChannel).should('be.focused'); + + // * Press Tab and verify if focus changes to Join button + cy.focused().tab(); + cy.findByText('Join').parent().should('be.focused'); + + // * Verify previous button should no longer be focused + cy.findByLabelText(selectedChannel).should('not.be.focused'); }); // * Press Tab again and verify if focus changes to next row diff --git a/e2e/cypress/tests/integration/channels/enterprise/ldap/ldap_group_sync_spec.js b/e2e/cypress/tests/integration/channels/enterprise/ldap/ldap_group_sync_spec.js index 75264a2aea..c7660753e0 100644 --- a/e2e/cypress/tests/integration/channels/enterprise/ldap/ldap_group_sync_spec.js +++ b/e2e/cypress/tests/integration/channels/enterprise/ldap/ldap_group_sync_spec.js @@ -234,7 +234,7 @@ context('ldap', () => { // * Search private channel name and make sure it isn't there in public channel directory cy.get('#searchChannelsTextbox').type(testChannel.display_name); - cy.get('#moreChannelsList').should('include.text', 'No results for'); + cy.get('#moreChannelsList').should('include.text', 'No more channels to join'); }); it('MM-T2629 - Private to public - More....', () => { @@ -473,7 +473,7 @@ context('ldap', () => { // * Search private channel name and make sure it isn't there in public channel directory cy.get('#searchChannelsTextbox').type(publicChannel.display_name); - cy.get('#moreChannelsList').should('include.text', 'No results for'); + cy.get('#moreChannelsList').should('include.text', 'No more channels to join'); }); }); diff --git a/webapp/channels/src/actions/channel_actions.test.ts b/webapp/channels/src/actions/channel_actions.test.ts index aac40512ec..6b247396b2 100644 --- a/webapp/channels/src/actions/channel_actions.test.ts +++ b/webapp/channels/src/actions/channel_actions.test.ts @@ -167,7 +167,7 @@ describe('Actions.Channel', () => { }], }]; - await testStore.dispatch(searchMoreChannels('', false, true)); + await testStore.dispatch(searchMoreChannels('', false)); expect(testStore.getActions()).toEqual(expectedActions); }); diff --git a/webapp/channels/src/actions/channel_actions.ts b/webapp/channels/src/actions/channel_actions.ts index 0add017514..b3c9ffb156 100644 --- a/webapp/channels/src/actions/channel_actions.ts +++ b/webapp/channels/src/actions/channel_actions.ts @@ -109,7 +109,7 @@ export function loadChannelsForCurrentUser(): ActionFunc { }; } -export function searchMoreChannels(term: string, showArchivedChannels: boolean, hideJoinedChannels: boolean): ActionFunc { +export function searchMoreChannels(term: string, showArchivedChannels: boolean): ActionFunc { return async (dispatch, getState) => { const state = getState(); const teamId = getCurrentTeamId(state); @@ -121,7 +121,9 @@ export function searchMoreChannels(term: string, showArchivedChannels: boolean, const {data, error} = await dispatch(ChannelActions.searchChannels(teamId, term, showArchivedChannels)); if (data) { const myMembers = getMyChannelMemberships(state); - const channels = hideJoinedChannels ? (data as Channel[]).filter((channel) => !myMembers[channel.id]) : data; + + // When searching public channels, only get channels user is not a member of + const channels = showArchivedChannels ? data : (data as Channel[]).filter((c) => !myMembers[c.id]); return {data: channels}; } diff --git a/webapp/channels/src/components/__snapshots__/searchable_channel_list.test.jsx.snap b/webapp/channels/src/components/__snapshots__/searchable_channel_list.test.jsx.snap new file mode 100644 index 0000000000..eff77678a4 --- /dev/null +++ b/webapp/channels/src/components/__snapshots__/searchable_channel_list.test.jsx.snap @@ -0,0 +1,46 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`components/SearchableChannelList should match init snapshot 1`] = ` +
+
+
+ +
+
+
+
+ +
+
+
+
+`; diff --git a/webapp/channels/src/components/common/svg_images_components/magnifying_glass_svg.tsx b/webapp/channels/src/components/common/svg_images_components/magnifying_glass_svg.tsx deleted file mode 100644 index 75b2ec8d3d..0000000000 --- a/webapp/channels/src/components/common/svg_images_components/magnifying_glass_svg.tsx +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -import React, {SVGProps} from 'react'; - -const SvgComponent = (props: SVGProps) => ( - - - - - - - -); - -export default SvgComponent; diff --git a/webapp/channels/src/components/generic_modal.scss b/webapp/channels/src/components/generic_modal.scss index 32ce008f2a..6cbca8629c 100644 --- a/webapp/channels/src/components/generic_modal.scss +++ b/webapp/channels/src/components/generic_modal.scss @@ -133,7 +133,6 @@ } .GenericModal__header { - width: 85%; padding: 0; border-top-left-radius: 12px; border-top-right-radius: 12px; diff --git a/webapp/channels/src/components/more_channels/__snapshots__/more_channels.test.tsx.snap b/webapp/channels/src/components/more_channels/__snapshots__/more_channels.test.tsx.snap index 1f2cd1c3d0..fe1acbf101 100644 --- a/webapp/channels/src/components/more_channels/__snapshots__/more_channels.test.tsx.snap +++ b/webapp/channels/src/components/more_channels/__snapshots__/more_channels.test.tsx.snap @@ -1,15 +1,53 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`components/MoreChannels should match snapshot and state 1`] = ` - + + + + + - - } - id="moreChannelsModal" - keyboardEscape={true} - modalHeaderText={ - + + + +

+ +

+ + } + search={[Function]} + shouldShowArchivedChannels={false} + toggleArchivedChannels={[Function]} /> - } - onExited={[Function]} - show={true} -> - -
+ + `; diff --git a/webapp/channels/src/components/more_channels/__snapshots__/searchable_channel_list.test.jsx.snap b/webapp/channels/src/components/more_channels/__snapshots__/searchable_channel_list.test.jsx.snap deleted file mode 100644 index 1118d16bf2..0000000000 --- a/webapp/channels/src/components/more_channels/__snapshots__/searchable_channel_list.test.jsx.snap +++ /dev/null @@ -1,82 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`components/SearchableChannelList should match init snapshot 1`] = ` -
-
- - -
-
- - 0 Results - -
-
-
-
-
-
-
- -
-
-
-
-`; diff --git a/webapp/channels/src/components/more_channels/index.ts b/webapp/channels/src/components/more_channels/index.ts index 7afbea20e2..d21425d99e 100644 --- a/webapp/channels/src/components/more_channels/index.ts +++ b/webapp/channels/src/components/more_channels/index.ts @@ -12,29 +12,24 @@ import {getConfig} from 'mattermost-redux/selectors/entities/general'; import {Action, ActionResult} from 'mattermost-redux/types/actions'; import {getCurrentTeam} from 'mattermost-redux/selectors/entities/teams'; import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users'; -import {getChannels, getArchivedChannels, joinChannel, getChannelStats} from 'mattermost-redux/actions/channels'; -import {getChannelsInCurrentTeam, getMyChannelMemberships, getAllChannelStats} from 'mattermost-redux/selectors/entities/channels'; - -import {Constants, StoragePrefixes} from 'utils/constants'; +import {getChannels, getArchivedChannels, joinChannel} from 'mattermost-redux/actions/channels'; +import {getOtherChannels, getChannelsInCurrentTeam} from 'mattermost-redux/selectors/entities/channels'; import {searchMoreChannels} from 'actions/channel_actions'; import {openModal, closeModal} from 'actions/views/modals'; -import {setGlobalItem} from 'actions/storage'; import {closeRightHandSide} from 'actions/views/rhs'; import {getIsRhsOpen, getRhsState} from 'selectors/rhs'; -import {GlobalState} from 'types/store'; import {ModalData} from 'types/actions'; - -import {makeGetGlobalItem} from 'selectors/storage'; +import {GlobalState} from 'types/store'; import MoreChannels from './more_channels'; -const getChannelsWithoutArchived = createSelector( - 'getChannelsWithoutArchived', - getChannelsInCurrentTeam, - (channels: Channel[]) => channels && channels.filter((c) => c.delete_at === 0 && c.type !== Constants.PRIVATE_CHANNEL), +const getNotArchivedOtherChannels = createSelector( + 'getNotArchivedOtherChannels', + getOtherChannels, + (channels: Channel[]) => channels && channels.filter((c) => c.delete_at === 0), ); const getArchivedOtherChannels = createSelector( @@ -45,19 +40,15 @@ const getArchivedOtherChannels = createSelector( function mapStateToProps(state: GlobalState) { const team = getCurrentTeam(state) || {}; - const getGlobalItem = makeGetGlobalItem(StoragePrefixes.HIDE_JOINED_CHANNELS, 'false'); return { - channels: getChannelsWithoutArchived(state) || [], + channels: getNotArchivedOtherChannels(state) || [], archivedChannels: getArchivedOtherChannels(state) || [], currentUserId: getCurrentUserId(state), teamId: team.id, teamName: team.name, channelsRequestStarted: state.requests.channels.getChannels.status === RequestStatus.STARTED, canShowArchivedChannels: (getConfig(state).ExperimentalViewArchivedChannels === 'true'), - myChannelMemberships: getMyChannelMemberships(state) || {}, - allChannelStats: getAllChannelStats(state) || {}, - shouldHideJoinedChannels: getGlobalItem(state) === 'true', rhsState: getRhsState(state), rhsOpen: getIsRhsOpen(state), }; @@ -70,8 +61,6 @@ type Actions = { searchMoreChannels: (term: string, shouldShowArchivedChannels: boolean) => Promise; openModal:

(modalData: ModalData

) => void; closeModal: (modalId: string) => void; - getChannelStats: (channelId: string) => void; - setGlobalItem: (name: string, value: string) => void; closeRightHandSide: () => void; } @@ -84,8 +73,6 @@ function mapDispatchToProps(dispatch: Dispatch) { searchMoreChannels, openModal, closeModal, - getChannelStats, - setGlobalItem, closeRightHandSide, }, dispatch), }; diff --git a/webapp/channels/src/components/more_channels/more_channels.scss b/webapp/channels/src/components/more_channels/more_channels.scss deleted file mode 100644 index d86fd138a7..0000000000 --- a/webapp/channels/src/components/more_channels/more_channels.scss +++ /dev/null @@ -1,295 +0,0 @@ -@charset 'UTF-8'; - -#moreChannelsModal { - .modal-content { - min-height: 600px; - max-height: calc(50vh - 240px); - } - - .modal-dialog { - margin-top: calc(45vh - 240px) !important; - } - - .filter-row--full { - position: relative; - margin: 0 32px; - - .input-clear { - top: 16px; - right: 16px; - } - - #searchIcon { - position: absolute; - top: 14px; - left: 16px; - color: rgba(var(--center-channel-color-rgb), 0.64); - pointer-events: none; - } - - #searchChannelsTextbox { - height: 48px; - padding-left: 40px; - border: 1px solid rgba(var(--center-channel-color-rgb), 0.16); - box-shadow: none; - font-size: 16px; - - &::placeholder { - color: var(--center-channel-color); - } - - &:focus { - border: 2px solid var(--button-bg); - } - } - } - - .more-modal__dropdown { - display: flex; - align-items: center; - justify-content: space-between; - padding: 8px 32px; - border-bottom: solid 1px rgba(var(--center-channel-color-rgb), 0.16); - margin: 0; - - span { - color: rgba(var(--center-channel-color-rgb), 0.64); - font-size: 12px; - line-height: 16px; - } - - .MenuItem__primary-text { - width: 100%; - color: var(--center-channel-color); - font-size: 14px; - font-weight: 400; - line-height: 20px; - - svg { - margin-left: auto; - } - } - - .Menu__content { - border-color: rgba(var(--center-channel-color-rgb), 0.16); - box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12); - } - - #channelCountLabel { - color: var(--center-channel-color); - font-size: 12px; - font-weight: 400; - } - - #modalPreferenceContainer { - display: flex; - align-items: center; - justify-content: center; - - .get-app__checkbox { - display: flex; - width: 16px; - height: 16px; - align-items: center; - border: 1px solid rgba(var(--center-channel-color-rgb), 0.24); - } - - #hideJoinedPreferenceCheckbox { - display: flex; - align-items: center; - cursor: pointer; - } - - #channelsMoreDropdown { - margin: 0 8px; - } - - #menuWrapper { - display: flex; - align-items: center; - justify-content: center; - padding: 4px 6px 4px 8px; - } - - .MenuWrapper:hover { - background-color: rgba(var(--center-channel-color-rgb), 0.08); - border-radius: 4px; - } - - .MenuWrapper--open { - background-color: rgba(var(--button-bg-rgb), 0.12); - border-radius: 4px; - - &:hover { - background-color: rgba(var(--button-bg-rgb), 0.12); - } - } - } - } - - .modal-body { - padding: 15px 0 0; - - .filtered-user-list { - height: 500px; - } - - .more-modal__row { - padding: 0 32px; - border-bottom: none; - - .more-modal__details { - padding-left: 0; - color: rgba(var(--center-channel-color-rgb), 0.56); - - svg { - flex-shrink: 0; - } - - .more-modal__name { - align-items: center; - margin-top: 0; - - span { - color: var(--center-channel-color); - font-weight: 500; - } - } - - #channelPurposeContainer { - display: flex; - align-items: center; - justify-content: flex-start; - - .dot { - width: 3px; - height: 3px; - flex-shrink: 0; - background-color: rgba(var(--center-channel-color-rgb), 0.56); - border-radius: 50%; - } - - .more-modal__description { - margin-left: 4px; - font-weight: 400; - } - - #membershipIndicatorContainer { - display: flex; - align-items: center; - - span, - svg { - color: var(--online-indicator); - } - } - - span { - margin: 0 4px; - font-size: 12px; - font-weight: 600; - line-height: 12px; - opacity: 1; - } - } - } - - .more-modal__actions { - button { - display: none; - min-width: 54px; - height: 32px; - font-size: 12px; - font-weight: 600; - } - } - } - - .more-modal__row:hover, - .more-modal__row:focus { - background-color: rgba(var(--center-channel-color-rgb), 0.08); - cursor: pointer; - - .more-modal__actions { - .primaryButton, - .outlineButton { - display: inline-block; - } - } - } - - .form-group { - padding: 0 32px; - margin-bottom: 0; - } - - ::-webkit-scrollbar { - width: 4px; - } - - ::-webkit-scrollbar-track { - background: none; - } - } - - .modal-header { - .GenericModal__header { - display: flex; - width: 95%; - align-items: center; - justify-content: space-between; - padding-right: 4px; - } - - .close { - top: 22px; - } - } - - .outlineButton { - border: 1px solid var(--button-bg); - background: none; - border-radius: 4px; - color: var(--button-bg); - font-size: 12px; - font-weight: 600; - line-height: 16px; - } - - .outlineButton:hover { - background-color: rgba(var(--button-bg-rgb), 0.08); - } - - .filter-controls { - padding: 0; - - button { - min-width: 72px; - margin: 8px 32px; - } - } -} - -#moreChannelsList { - .primary-message { - margin-top: 8px; - color: var(--center-channel-color); - line-height: 28px; - } - - .secondary-message { - margin-bottom: 30px; - } - - .primaryButton { - background-color: var(--button-bg); - border-radius: 4px; - color: var(--button-color); - font-size: 14px; - font-weight: 600; - } - - #createNewChannelButton { - padding: 10px 20px; - } -} diff --git a/webapp/channels/src/components/more_channels/more_channels.test.tsx b/webapp/channels/src/components/more_channels/more_channels.test.tsx index 4d05021650..a591bfef5b 100644 --- a/webapp/channels/src/components/more_channels/more_channels.test.tsx +++ b/webapp/channels/src/components/more_channels/more_channels.test.tsx @@ -7,7 +7,7 @@ import {shallow} from 'enzyme'; import {ActionResult} from 'mattermost-redux/types/actions'; import MoreChannels, {Props} from 'components/more_channels/more_channels'; -import SearchableChannelList from 'components/more_channels/searchable_channel_list.jsx'; +import SearchableChannelList from 'components/searchable_channel_list.jsx'; import {getHistory} from 'utils/browser_history'; import {TestHelper} from 'utils/test_helper'; @@ -59,16 +59,7 @@ describe('components/MoreChannels', () => { }; const baseProps: Props = { - channels: [ - TestHelper.getChannelMock({ - id: 'channel-1', - name: 'channel-1', - }), - TestHelper.getChannelMock({ - id: 'channel-2', - name: 'channel-2', - }), - ], + channels: [TestHelper.getChannelMock({})], archivedChannels: [TestHelper.getChannelMock({ id: 'channel_id_2', team_id: 'channel_team_2', @@ -82,14 +73,6 @@ describe('components/MoreChannels', () => { teamName: 'team_name', channelsRequestStarted: false, canShowArchivedChannels: true, - myChannelMemberships: { - 'channel-2': TestHelper.getChannelMembershipMock({ - channel_id: 'channel-2', - user_id: 'user-1', - }), - }, - allChannelStats: {}, - shouldHideJoinedChannels: false, actions: { getChannels: jest.fn(), getArchivedChannels: jest.fn(), @@ -97,8 +80,6 @@ describe('components/MoreChannels', () => { searchMoreChannels: jest.fn(channelActions.searchMoreChannels), openModal: jest.fn(), closeModal: jest.fn(), - getChannelStats: jest.fn(), - setGlobalItem: jest.fn(), closeRightHandSide: jest.fn(), }, }; @@ -110,6 +91,7 @@ describe('components/MoreChannels', () => { expect(wrapper).toMatchSnapshot(); expect(wrapper.state('searchedChannels')).toEqual([]); + expect(wrapper.state('show')).toEqual(true); expect(wrapper.state('shouldShowArchivedChannels')).toEqual(false); expect(wrapper.state('search')).toEqual(false); expect(wrapper.state('serverError')).toBeNull(); @@ -120,6 +102,16 @@ describe('components/MoreChannels', () => { expect(wrapper.instance().props.actions.getChannels).toHaveBeenCalledWith(wrapper.instance().props.teamId, 0, 100); }); + test('should match state on handleHide', () => { + const wrapper = shallow( + , + ); + wrapper.setState({show: true}); + + wrapper.instance().handleHide(); + expect(wrapper.state('show')).toEqual(false); + }); + test('should call closeModal on handleExit', () => { const wrapper = shallow( , @@ -160,7 +152,7 @@ describe('components/MoreChannels', () => { , ); - wrapper.setState({loading: false, search: true, searching: true}); + wrapper.setState({search: true, searching: true}); const searchList = wrapper.find(SearchableChannelList); expect(searchList.props().loading).toEqual(true); }); @@ -219,6 +211,7 @@ describe('components/MoreChannels', () => { process.nextTick(() => { expect(getHistory().push).toHaveBeenCalledTimes(1); expect(callback).toHaveBeenCalledTimes(1); + expect(wrapper.state('show')).toEqual(false); done(); }); }); @@ -256,7 +249,7 @@ describe('components/MoreChannels', () => { jest.runOnlyPendingTimers(); expect(wrapper.instance().props.actions.searchMoreChannels).toHaveBeenCalledTimes(1); - expect(wrapper.instance().props.actions.searchMoreChannels).toHaveBeenCalledWith('fail', false, false); + expect(wrapper.instance().props.actions.searchMoreChannels).toHaveBeenCalledWith('fail', false); process.nextTick(() => { expect(wrapper.state('search')).toEqual(true); expect(wrapper.state('searching')).toEqual(false); @@ -283,7 +276,7 @@ describe('components/MoreChannels', () => { jest.runOnlyPendingTimers(); expect(wrapper.instance().props.actions.searchMoreChannels).toHaveBeenCalledTimes(1); - expect(wrapper.instance().props.actions.searchMoreChannels).toHaveBeenCalledWith('channel', false, false); + expect(wrapper.instance().props.actions.searchMoreChannels).toHaveBeenCalledWith('channel', false); process.nextTick(() => { expect(wrapper.state('search')).toEqual(true); expect(wrapper.state('searching')).toEqual(false); @@ -310,7 +303,7 @@ describe('components/MoreChannels', () => { jest.runOnlyPendingTimers(); expect(wrapper.instance().props.actions.searchMoreChannels).toHaveBeenCalledTimes(1); - expect(wrapper.instance().props.actions.searchMoreChannels).toHaveBeenCalledWith('channel', true, false); + expect(wrapper.instance().props.actions.searchMoreChannels).toHaveBeenCalledWith('channel', true); process.nextTick(() => { expect(wrapper.state('search')).toEqual(true); expect(wrapper.state('searching')).toEqual(false); @@ -318,16 +311,4 @@ describe('components/MoreChannels', () => { done(); }); }); - - test('should hide joined channels from channels props when shouldHideJoinedChannels prop is true', () => { - const props = { - ...baseProps, - shouldHideJoinedChannels: true, - }; - const wrapper = shallow( - , - ); - - expect(wrapper.instance().activeChannels).not.toContain(baseProps.channels[1]); - }); }); diff --git a/webapp/channels/src/components/more_channels/more_channels.tsx b/webapp/channels/src/components/more_channels/more_channels.tsx index 235744166e..b51606db19 100644 --- a/webapp/channels/src/components/more_channels/more_channels.tsx +++ b/webapp/channels/src/components/more_channels/more_channels.tsx @@ -2,32 +2,23 @@ // See LICENSE.txt for license information. import React from 'react'; +import {Modal} from 'react-bootstrap'; import {FormattedMessage} from 'react-intl'; -import classNames from 'classnames'; - import {ActionResult} from 'mattermost-redux/types/actions'; -import {Channel, ChannelMembership, ChannelStats} from '@mattermost/types/channels'; +import {Channel} from '@mattermost/types/channels'; import Permissions from 'mattermost-redux/constants/permissions'; -import {RelationOneToOne} from '@mattermost/types/utilities'; - import NewChannelModal from 'components/new_channel_modal/new_channel_modal'; +import SearchableChannelList from 'components/searchable_channel_list.jsx'; import TeamPermissionGate from 'components/permissions_gates/team_permission_gate'; -import GenericModal from 'components/generic_modal'; -import LoadingScreen from 'components/loading_screen'; import {ModalData} from 'types/actions'; import {RhsState} from 'types/store/rhs'; import {getHistory} from 'utils/browser_history'; -import {ModalIdentifiers, StoragePrefixes, RHSStates} from 'utils/constants'; +import {ModalIdentifiers, RHSStates} from 'utils/constants'; import {getRelativeChannelURL} from 'utils/url'; -import {localizeMessage} from 'utils/utils'; - -import SearchableChannelList from './searchable_channel_list'; - -import './more_channels.scss'; const CHANNELS_CHUNK_SIZE = 50; const CHANNELS_PER_PAGE = 50; @@ -37,15 +28,9 @@ type Actions = { getChannels: (teamId: string, page: number, perPage: number) => void; getArchivedChannels: (teamId: string, page: number, channelsPerPage: number) => void; joinChannel: (currentUserId: string, teamId: string, channelId: string) => Promise; - searchMoreChannels: (term: string, shouldShowArchivedChannels: boolean, shouldHideJoinedChannels: boolean) => Promise; + searchMoreChannels: (term: string, shouldShowArchivedChannels: boolean) => Promise; openModal:

(modalData: ModalData

) => void; closeModal: (modalId: string) => void; - getChannelStats: (channelId: string) => void; - - /* - * Function to set a key-value pair in the local storage - */ - setGlobalItem: (name: string, value: string) => void; closeRightHandSide: () => void; } @@ -58,27 +43,23 @@ export type Props = { channelsRequestStarted?: boolean; canShowArchivedChannels?: boolean; morePublicChannelsModalType?: string; - myChannelMemberships: RelationOneToOne; - allChannelStats: RelationOneToOne; - shouldHideJoinedChannels: boolean; rhsState?: RhsState; rhsOpen?: boolean; actions: Actions; } type State = { + show: boolean; shouldShowArchivedChannels: boolean; search: boolean; searchedChannels: Channel[]; serverError: React.ReactNode | string; searching: boolean; searchTerm: string; - loading: boolean; } export default class MoreChannels extends React.PureComponent { public searchTimeoutId: number; - activeChannels: Channel[] = []; constructor(props: Props) { super(props); @@ -86,27 +67,25 @@ export default class MoreChannels extends React.PureComponent { this.searchTimeoutId = 0; this.state = { + show: true, shouldShowArchivedChannels: this.props.morePublicChannelsModalType === 'private', search: false, searchedChannels: [], serverError: null, searching: false, searchTerm: '', - loading: true, }; } - async componentDidMount() { - await this.props.actions.getChannels(this.props.teamId, 0, CHANNELS_CHUNK_SIZE * 2); + componentDidMount() { + this.props.actions.getChannels(this.props.teamId, 0, CHANNELS_CHUNK_SIZE * 2); if (this.props.canShowArchivedChannels) { - await this.props.actions.getArchivedChannels(this.props.teamId, 0, CHANNELS_CHUNK_SIZE * 2); + this.props.actions.getArchivedChannels(this.props.teamId, 0, CHANNELS_CHUNK_SIZE * 2); } - await this.props.channels.forEach((channel) => this.props.actions.getChannelStats(channel.id)); - this.loadComplete(); } - loadComplete = () => { - this.setState({loading: false}); + handleHide = () => { + this.setState({show: false}); } handleNewChannel = () => { @@ -145,17 +124,14 @@ export default class MoreChannels extends React.PureComponent { handleJoin = async (channel: Channel, done: () => void) => { const {actions, currentUserId, teamId, teamName} = this.props; - let result; + const result = await actions.joinChannel(currentUserId, teamId, channel.id); - if (!this.isMemberOfChannel(channel.id)) { - result = await actions.joinChannel(currentUserId, teamId, channel.id); - } - - if (result?.error) { + if (result.error) { this.setState({serverError: result.error.message}); } else { getHistory().push(getRelativeChannelURL(teamName, channel.name)); this.closeEditRHS(); + this.handleHide(); } if (done) { @@ -177,7 +153,7 @@ export default class MoreChannels extends React.PureComponent { const searchTimeoutId = window.setTimeout( async () => { try { - const {data} = await this.props.actions.searchMoreChannels(term, this.state.shouldShowArchivedChannels, this.props.shouldHideJoinedChannels); + const {data} = await this.props.actions.searchMoreChannels(term, this.state.shouldShowArchivedChannels); if (searchTimeoutId !== this.searchTimeoutId) { return; } @@ -207,47 +183,29 @@ export default class MoreChannels extends React.PureComponent { this.setState({shouldShowArchivedChannels}); } - isMemberOfChannel(channelId: string) { - return this.props.myChannelMemberships[channelId]; - } - - handleShowJoinedChannelsPreference = (shouldHideJoinedChannels: boolean) => { - // search again when switching channels to update search results - this.search(this.state.searchTerm); - this.props.actions.setGlobalItem(StoragePrefixes.HIDE_JOINED_CHANNELS, shouldHideJoinedChannels.toString()); - } - - otherChannelsWithoutJoined = this.props.channels.filter((channel) => !this.isMemberOfChannel(channel.id)); - archivedChannelsWithoutJoined = this.props.archivedChannels.filter((channel) => !this.isMemberOfChannel(channel.id)); - render() { const { channels, archivedChannels, teamId, channelsRequestStarted, - shouldHideJoinedChannels, } = this.props; const { search, searchedChannels, serverError: serverErrorState, + show, searching, shouldShowArchivedChannels, } = this.state; - const otherChannelsWithoutJoined = channels.filter((channel) => !this.isMemberOfChannel(channel.id)); - const archivedChannelsWithoutJoined = archivedChannels.filter((channel) => !this.isMemberOfChannel(channel.id)); + let activeChannels; - if (shouldShowArchivedChannels && shouldHideJoinedChannels) { - this.activeChannels = search ? searchedChannels : archivedChannelsWithoutJoined; - } else if (shouldShowArchivedChannels && !shouldHideJoinedChannels) { - this.activeChannels = search ? searchedChannels : archivedChannels; - } else if (!shouldShowArchivedChannels && shouldHideJoinedChannels) { - this.activeChannels = search ? searchedChannels : otherChannelsWithoutJoined; + if (shouldShowArchivedChannels) { + activeChannels = search ? searchedChannels : archivedChannels; } else { - this.activeChannels = search ? searchedChannels : channels; + activeChannels = search ? searchedChannels : channels; } let serverError; @@ -256,87 +214,87 @@ export default class MoreChannels extends React.PureComponent {

; } - const createNewChannelButton = (className: string, icon?: JSX.Element) => { - const buttonClassName = classNames('btn', className); - return ( - + - - ); - }; - - const noResultsText = ( - <> -

-

- {createNewChannelButton('primaryButton', )} - + + ); - const body = this.state.loading ? : ( + const createChannelHelpText = ( + +

+ +

+
+ ); + + const body = ( {serverError} ); - const title = ( - - ); - return ( - - {body} - + + + + + {createNewChannelButton} + + + {body} + + ); } } diff --git a/webapp/channels/src/components/more_channels/searchable_channel_list.jsx b/webapp/channels/src/components/more_channels/searchable_channel_list.jsx deleted file mode 100644 index 0efe317296..0000000000 --- a/webapp/channels/src/components/more_channels/searchable_channel_list.jsx +++ /dev/null @@ -1,483 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -import PropTypes from 'prop-types'; -import React from 'react'; -import {FormattedMessage} from 'react-intl'; - -import {AccountOutlineIcon, ArchiveOutlineIcon, CheckIcon, ChevronDownIcon, GlobeIcon, LockOutlineIcon, MagnifyIcon} from '@mattermost/compass-icons/components'; - -import classNames from 'classnames'; - -import {isPrivateChannel} from 'mattermost-redux/utils/channel_utils'; - -import LoadingScreen from 'components/loading_screen'; -import LoadingWrapper from 'components/widgets/loading/loading_wrapper'; -import QuickInput from 'components/quick_input'; -import LocalizedInput from 'components/localized_input/localized_input'; -import CheckboxCheckedIcon from 'components/widgets/icons/checkbox_checked_icon'; -import MagnifyingGlassSVG from 'components/common/svg_images_components/magnifying_glass_svg'; -import MenuWrapper from 'components/widgets/menu/menu_wrapper'; -import Menu from 'components/widgets/menu/menu'; - -import {t} from 'utils/i18n'; -import * as UserAgent from 'utils/user_agent'; -import Constants, {ModalIdentifiers} from 'utils/constants'; -import {isKeyPressed, localizeMessage, localizeAndFormatMessage} from 'utils/utils'; - -import {isArchivedChannel} from 'utils/channel_utils'; - -const NEXT_BUTTON_TIMEOUT_MILLISECONDS = 500; - -export default class SearchableChannelList extends React.PureComponent { - static getDerivedStateFromProps(props, state) { - return {isSearch: props.isSearch, page: props.isSearch && !state.isSearch ? 0 : state.page}; - } - - constructor(props) { - super(props); - - this.nextTimeoutId = 0; - - this.state = { - joiningChannel: '', - page: 0, - nextDisabled: false, - channelSearchValue: '', - }; - - this.filter = React.createRef(); - this.channelListScroll = React.createRef(); - } - - componentDidMount() { - // only focus the search box on desktop so that we don't cause the keyboard to open on mobile - if (!UserAgent.isMobile() && this.filter.current) { - this.filter.current.focus(); - } - document.addEventListener('keydown', this.onKeyDown); - } - - componentWillUnmount() { - document.removeEventListener('keydown', this.onKeyDown); - } - - onKeyDown = (e) => { - const target = e.target; - const isEnterKeyPressed = isKeyPressed(e, Constants.KeyCodes.ENTER); - if (isEnterKeyPressed && (e.shiftKey || e.ctrlKey || e.altKey)) { - return; - } - if (isEnterKeyPressed && target.classList.contains('more-modal__row')) { - target.click(); - } - } - - handleJoin = (channel, e) => { - e.stopPropagation(); - this.setState({joiningChannel: channel.id}); - this.props.handleJoin( - channel, - () => { - this.setState({joiningChannel: ''}); - }, - ); - if (this.isMemberOfChannel(channel.id)) { - this.props.closeModal(ModalIdentifiers.MORE_CHANNELS); - } - } - - isMemberOfChannel(channelId) { - return this.props.myChannelMemberships[channelId]; - } - - createChannelRow = (channel) => { - const ariaLabel = `${channel.display_name}, ${channel.purpose}`.toLowerCase(); - let channelTypeIcon; - - let memberCount = 0; - if (this.props.allChannelStats[channel.id]) { - memberCount = this.props.allChannelStats[channel.id].member_count; - } - - if (isArchivedChannel(channel)) { - channelTypeIcon = ; - } else if (isPrivateChannel(channel)) { - channelTypeIcon = ; - } else { - channelTypeIcon = ; - } - - const membershipIndicator = this.isMemberOfChannel(channel.id) ? ( -
- - - -
- ) : null; - - const channelPurposeContainerAriaLabel = localizeAndFormatMessage( - t('more_channels.channel_purpose'), - 'Channel Information: Membership Indicator: Joined, Member count {memberCount} , Purpose: {channelPurpose}', - {memberCount, channelPurpose: channel.purpose || ''}, - ); - - const channelPurposeContainer = ( -
- {membershipIndicator} - - {memberCount} - {channel.purpose.length > 0 && } - {channel.purpose} -
- ); - - const joinViewChannelButtonClass = classNames('btn', { - outlineButton: this.isMemberOfChannel(channel.id), - primaryButton: !this.isMemberOfChannel(channel.id), - }); - - const joinViewChannelButton = ( - - ); - - return ( -
this.handleJoin(channel, e)} - tabIndex={0} - > -
-
- {channelTypeIcon} - {channel.display_name} -
- {channelPurposeContainer} -
-
- {joinViewChannelButton} -
-
- ); - } - - nextPage = (e) => { - e.preventDefault(); - this.setState({page: this.state.page + 1, nextDisabled: true}); - this.nextTimeoutId = setTimeout(() => this.setState({nextDisabled: false}), NEXT_BUTTON_TIMEOUT_MILLISECONDS); - this.props.nextPage(this.state.page + 1); - this.channelListScroll.current?.scrollTo({top: 0}); - } - - previousPage = (e) => { - e.preventDefault(); - this.setState({page: this.state.page - 1}); - this.channelListScroll.current?.scrollTo({top: 0}); - } - - doSearch = () => { - this.props.search(this.state.channelSearchValue); - if (this.state.channelSearchValue === '') { - this.setState({page: 0}); - } - } - - handleChange = (e) => { - if (e.target) { - this.setState({channelSearchValue: e.target.value}, () => this.doSearch()); - } - } - - handleClear = () => { - this.setState({channelSearchValue: ''}, () => this.doSearch()); - } - - toggleArchivedChannelsOn = () => { - this.props.toggleArchivedChannels(true); - } - - toggleArchivedChannelsOff = () => { - this.props.toggleArchivedChannels(false); - } - - handleChecked = () => { - // If it was checked, and now we're unchecking it, clear the preference - if (this.props.rememberHideJoinedChannelsChecked) { - this.props.hideJoinedChannelsPreference(false); - } else { - this.props.hideJoinedChannelsPreference(true); - } - } - - render() { - const channels = this.props.channels; - let listContent; - let nextButton; - let previousButton; - - let emptyStateMessage = ( - - ); - - if (this.state.channelSearchValue.length > 0) { - emptyStateMessage = ( - - ); - } - - if (this.props.loading && channels.length === 0) { - listContent = ; - } else if (channels.length === 0) { - listContent = ( -
0 ? - localizeAndFormatMessage(t('more_channels.noMore'), 'No results for {text}', {text: this.state.channelSearchValue}) : - localizeMessage('widgets.channels_input.empty', 'No channels found') - } - > - -

- {emptyStateMessage} -

- {this.props.noResultsText} -
- ); - } else { - const pageStart = this.state.page * this.props.channelsPerPage; - const pageEnd = pageStart + this.props.channelsPerPage; - const channelsToDisplay = this.props.channels.slice(pageStart, pageEnd); - listContent = channelsToDisplay.map(this.createChannelRow); - - if (channelsToDisplay.length >= this.props.channelsPerPage && pageEnd < this.props.channels.length) { - nextButton = ( - - ); - } - - if (this.state.page > 0) { - previousButton = ( - - ); - } - } - - const input = ( -
- - -
- ); - - let channelDropdown; - let checkIcon; - - if (this.props.canShowArchivedChannels) { - checkIcon = ( - - ); - channelDropdown = ( - - - {this.props.shouldShowArchivedChannels ? localizeMessage('more_channels.show_archived_channels', 'Channel Type: Archived') : localizeMessage('more_channels.show_public_channels', 'Channel Type: Public')} - - - -
- } - text={localizeMessage('suggestion.search.public', 'Public Channels')} - rightDecorator={this.props.shouldShowArchivedChannels ? null : checkIcon} - ariaLabel={localizeMessage('suggestion.search.public', 'Public Channels')} - /> -
- } - text={localizeMessage('suggestion.archive', 'Archived Channels')} - rightDecorator={this.props.shouldShowArchivedChannels ? checkIcon : null} - ariaLabel={localizeMessage('suggestion.archive', 'Archived Channels')} - /> -
-
- ); - } - - const hideJoinedButtonClass = classNames('get-app__checkbox', {checked: this.props.rememberHideJoinedChannelsChecked}); - const hideJoinedPreferenceCheckbox = ( -
- - -
- ); - - let channelCountLabel; - if (channels.length === 0) { - channelCountLabel = localizeMessage('more_channels.count_zero', '0 Results'); - } else if (channels.length === 1) { - channelCountLabel = localizeMessage('more_channels.count_one', '1 Result'); - } else if (channels.length > 1) { - channelCountLabel = localizeAndFormatMessage(t('more_channels.count'), '0 Results', {count: channels.length}); - } else { - channelCountLabel = localizeMessage('more_channels.count_zero', '0 Results'); - } - - const dropDownContainer = ( -
- {channelCountLabel} -
- {channelDropdown} - {hideJoinedPreferenceCheckbox} -
-
- ); - - return ( -
- {input} - {dropDownContainer} -
-
- {listContent} -
-
-
- {previousButton} - {nextButton} -
-
- ); - } -} - -SearchableChannelList.defaultProps = { - channels: [], - isSearch: false, -}; - -SearchableChannelList.propTypes = { - channels: PropTypes.arrayOf(PropTypes.object), - channelsPerPage: PropTypes.number, - nextPage: PropTypes.func.isRequired, - isSearch: PropTypes.bool, - search: PropTypes.func.isRequired, - handleJoin: PropTypes.func.isRequired, - noResultsText: PropTypes.object, - loading: PropTypes.bool, - toggleArchivedChannels: PropTypes.func.isRequired, - shouldShowArchivedChannels: PropTypes.bool.isRequired, - canShowArchivedChannels: PropTypes.bool.isRequired, - myChannelMemberships: PropTypes.object.isRequired, - allChannelStats: PropTypes.object.isRequired, - closeModal: PropTypes.func.isRequired, - hideJoinedChannelsPreference: PropTypes.func.isRequired, - rememberHideJoinedChannelsChecked: PropTypes.bool.isRequired, -}; -/* eslint-enable react/no-string-refs */ diff --git a/webapp/channels/src/components/searchable_channel_list.jsx b/webapp/channels/src/components/searchable_channel_list.jsx new file mode 100644 index 0000000000..edf7b57565 --- /dev/null +++ b/webapp/channels/src/components/searchable_channel_list.jsx @@ -0,0 +1,319 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import PropTypes from 'prop-types'; +import React from 'react'; +import {FormattedMessage} from 'react-intl'; + +import {ArchiveOutlineIcon} from '@mattermost/compass-icons/components'; + +import LoadingScreen from 'components/loading_screen'; +import LoadingWrapper from 'components/widgets/loading/loading_wrapper'; +import QuickInput from 'components/quick_input'; +import * as UserAgent from 'utils/user_agent'; +import {localizeMessage} from 'utils/utils'; +import LocalizedInput from 'components/localized_input/localized_input'; + +import SharedChannelIndicator from 'components/shared_channel_indicator'; + +import {t} from 'utils/i18n'; + +import MenuWrapper from './widgets/menu/menu_wrapper'; +import Menu from './widgets/menu/menu'; + +const NEXT_BUTTON_TIMEOUT_MILLISECONDS = 500; + +export default class SearchableChannelList extends React.PureComponent { + static getDerivedStateFromProps(props, state) { + return {isSearch: props.isSearch, page: props.isSearch && !state.isSearch ? 0 : state.page}; + } + + constructor(props) { + super(props); + + this.nextTimeoutId = 0; + + this.state = { + joiningChannel: '', + page: 0, + nextDisabled: false, + }; + + this.filter = React.createRef(); + this.channelListScroll = React.createRef(); + } + + componentDidMount() { + // only focus the search box on desktop so that we don't cause the keyboard to open on mobile + if (!UserAgent.isMobile() && this.filter.current) { + this.filter.current.focus(); + } + } + + handleJoin(channel) { + this.setState({joiningChannel: channel.id}); + this.props.handleJoin( + channel, + () => { + this.setState({joiningChannel: ''}); + }, + ); + } + + createChannelRow = (channel) => { + const ariaLabel = `${channel.display_name}, ${channel.purpose}`.toLowerCase(); + let archiveIcon; + let sharedIcon; + const {shouldShowArchivedChannels} = this.props; + + if (shouldShowArchivedChannels) { + archiveIcon = ( + + ); + } + + if (channel.shared) { + sharedIcon = ( + + ); + } + + return ( +
+
+ +

{channel.purpose}

+
+
+ +
+
+ ); + } + + nextPage = (e) => { + e.preventDefault(); + this.setState({page: this.state.page + 1, nextDisabled: true}); + this.nextTimeoutId = setTimeout(() => this.setState({nextDisabled: false}), NEXT_BUTTON_TIMEOUT_MILLISECONDS); + this.props.nextPage(this.state.page + 1); + this.channelListScroll.current?.scrollTo({top: 0}); + } + + previousPage = (e) => { + e.preventDefault(); + this.setState({page: this.state.page - 1}); + this.channelListScroll.current?.scrollTo({top: 0}); + } + + doSearch = () => { + const term = this.filter.current.value; + this.props.search(term); + if (term === '') { + this.setState({page: 0}); + } + } + toggleArchivedChannelsOn = () => { + this.props.toggleArchivedChannels(true); + } + toggleArchivedChannelsOff = () => { + this.props.toggleArchivedChannels(false); + } + + render() { + const channels = this.props.channels; + let listContent; + let nextButton; + let previousButton; + + if (this.props.loading && channels.length === 0) { + listContent = ; + } else if (channels.length === 0) { + listContent = ( +
+

+ +

+ {this.props.noResultsText} +
+ ); + } else { + const pageStart = this.state.page * this.props.channelsPerPage; + const pageEnd = pageStart + this.props.channelsPerPage; + const channelsToDisplay = this.props.channels.slice(pageStart, pageEnd); + listContent = channelsToDisplay.map(this.createChannelRow); + + if (channelsToDisplay.length >= this.props.channelsPerPage && pageEnd < this.props.channels.length) { + nextButton = ( + + ); + } + + if (this.state.page > 0) { + previousButton = ( + + ); + } + } + + let input = ( +
+
+ +
+
+ ); + + if (this.props.createChannelButton) { + input = ( +
+
+ +
+
+ {this.props.createChannelButton} +
+
+ ); + } + + let channelDropdown; + + if (this.props.canShowArchivedChannels) { + channelDropdown = ( + + ); + } + + return ( +
+ {input} + {channelDropdown} +
+
+ {listContent} +
+
+
+ {previousButton} + {nextButton} +
+
+ ); + } +} + +SearchableChannelList.defaultProps = { + channels: [], + isSearch: false, +}; + +SearchableChannelList.propTypes = { + channels: PropTypes.arrayOf(PropTypes.object), + channelsPerPage: PropTypes.number, + nextPage: PropTypes.func.isRequired, + isSearch: PropTypes.bool, + search: PropTypes.func.isRequired, + handleJoin: PropTypes.func.isRequired, + noResultsText: PropTypes.object, + loading: PropTypes.bool, + createChannelButton: PropTypes.element, + toggleArchivedChannels: PropTypes.func.isRequired, + shouldShowArchivedChannels: PropTypes.bool.isRequired, + canShowArchivedChannels: PropTypes.bool.isRequired, +}; diff --git a/webapp/channels/src/components/more_channels/searchable_channel_list.test.jsx b/webapp/channels/src/components/searchable_channel_list.test.jsx similarity index 70% rename from webapp/channels/src/components/more_channels/searchable_channel_list.test.jsx rename to webapp/channels/src/components/searchable_channel_list.test.jsx index 9953b08225..9ba5ddd4f8 100644 --- a/webapp/channels/src/components/more_channels/searchable_channel_list.test.jsx +++ b/webapp/channels/src/components/searchable_channel_list.test.jsx @@ -4,25 +4,20 @@ import React from 'react'; import {shallow} from 'enzyme'; -import SearchableChannelList from './searchable_channel_list.jsx'; +import SearchableChannelList from 'components/searchable_channel_list.jsx'; describe('components/SearchableChannelList', () => { const baseProps = { channels: [], isSearch: false, channelsPerPage: 10, - nextPage: jest.fn(), - search: jest.fn(), - handleJoin: jest.fn(), + nextPage: () => {}, // eslint-disable-line no-empty-function + search: () => {}, // eslint-disable-line no-empty-function + handleJoin: () => {}, // eslint-disable-line no-empty-function loading: true, - rememberHideJoinedChannelsChecked: false, - toggleArchivedChannels: jest.fn(), + toggleArchivedChannels: () => {}, // eslint-disable-line no-empty-function shouldShowArchivedChannels: false, canShowArchivedChannels: false, - myChannelMemberships: {}, - allChannelStats: {}, - closeModal: jest.fn(), - hideJoinedChannelsPreference: jest.fn(), }; test('should match init snapshot', () => { diff --git a/webapp/channels/src/i18n/en.json b/webapp/channels/src/i18n/en.json index 6c28bff86c..f84245884b 100644 --- a/webapp/channels/src/i18n/en.json +++ b/webapp/channels/src/i18n/en.json @@ -4155,22 +4155,13 @@ "modal.manual_status.title_dnd": "Your Status is Set to \"Do Not Disturb\"", "modal.manual_status.title_offline": "Your Status is Set to \"Offline\"", "modal.manual_status.title_ooo": "Your Status is Set to \"Out of Office\"", - "more_channels.channel_purpose": "Channel Information: Membership Indicator: Joined, Member count {memberCount} , Purpose: {channelPurpose}", - "more_channels.count": "{count} Results", - "more_channels.count_one": "1 Result", - "more_channels.count_zero": "0 Results", "more_channels.create": "Create New Channel", - "more_channels.hide_joined": "Hide Joined", - "more_channels.hide_joined_checked": "Hide joined channels checkbox, checked", - "more_channels.hide_joined_not_checked": "Hide joined channels checkbox, not checked", - "more_channels.joined": "Joined", - "more_channels.membership_indicator": "Membership Indicator: Joined", + "more_channels.createClick": "Click 'Create New Channel' to make a new one", + "more_channels.join": "Join", + "more_channels.joining": "Joining...", "more_channels.next": "Next", - "more_channels.noArchived": "No archived channels", "more_channels.noMore": "No results for \"{text}\"", - "more_channels.noPublic": "No public channels", "more_channels.prev": "Previous", - "more_channels.searchError": "Try searching different keywords, checking for typos or adjusting the filters.", "more_channels.show_archived_channels": "Channel Type: Archived", "more_channels.show_public_channels": "Channel Type: Public", "more_channels.title": "Browse Channels", diff --git a/webapp/channels/src/sass/components/_channel-invite-modal.scss b/webapp/channels/src/sass/components/_channel-invite-modal.scss index d3e70e8398..f1893c9a76 100644 --- a/webapp/channels/src/sass/components/_channel-invite-modal.scss +++ b/webapp/channels/src/sass/components/_channel-invite-modal.scss @@ -71,9 +71,7 @@ .primary-message { margin: 0; - color: var(--center-channel-color); font-size: inherit; - line-height: 28px; } } diff --git a/webapp/channels/src/utils/constants.tsx b/webapp/channels/src/utils/constants.tsx index d3426a4395..5a5825ec5a 100644 --- a/webapp/channels/src/utils/constants.tsx +++ b/webapp/channels/src/utils/constants.tsx @@ -896,7 +896,6 @@ export const StoragePrefixes = { CHANNEL_CATEGORY_COLLAPSED: 'channelCategoryCollapsed_', INLINE_IMAGE_VISIBLE: 'isInlineImageVisible_', DELINQUENCY: 'delinquency_', - HIDE_JOINED_CHANNELS: 'hideJoinedChannels', }; export const LandingPreferenceTypes = { diff --git a/webapp/platform/components/src/generic_modal/generic_modal.tsx b/webapp/platform/components/src/generic_modal/generic_modal.tsx index 117d1d4b58..9f5ea7a357 100644 --- a/webapp/platform/components/src/generic_modal/generic_modal.tsx +++ b/webapp/platform/components/src/generic_modal/generic_modal.tsx @@ -38,7 +38,6 @@ export type Props = { compassDesign?: boolean; backdrop?: boolean; backdropClassName?: string; - headerButton?: React.ReactNode; tabIndex?: number; children: React.ReactNode; keyboardEscape?: boolean; @@ -166,7 +165,6 @@ export class GenericModal extends React.PureComponent {

{this.props.modalHeaderText}

- {this.props.headerButton}
); From 2287dff298b7d240ac095f7bc2cd9da6a56b472d Mon Sep 17 00:00:00 2001 From: Agniva De Sarker Date: Tue, 28 Mar 2023 09:04:09 +0530 Subject: [PATCH 30/46] MM-51700: Suppress websocket warnings with a threshold (#22637) We log warnings whenever our websocket buffer sizes exceed certain thresholds. The problem with that is, when this happens, the logs are completely spammed with these lines making it annoying for the customer. To improve the situation, we use a timer that only gets reset every minute. https://mattermost.atlassian.net/browse/MM-51700 ```release-note NONE ``` --- server/channels/app/platform/web_conn.go | 45 ++++++++++++++++-------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/server/channels/app/platform/web_conn.go b/server/channels/app/platform/web_conn.go index 02b8cd8687..ac72c98cdf 100644 --- a/server/channels/app/platform/web_conn.go +++ b/server/channels/app/platform/web_conn.go @@ -27,15 +27,16 @@ import ( ) const ( - sendQueueSize = 256 - sendSlowWarn = (sendQueueSize * 50) / 100 - sendFullWarn = (sendQueueSize * 95) / 100 - writeWaitTime = 30 * time.Second - pongWaitTime = 100 * time.Second - pingInterval = (pongWaitTime * 6) / 10 - authCheckInterval = 5 * time.Second - webConnMemberCacheTime = 1000 * 60 * 30 // 30 minutes - deadQueueSize = 128 // Approximated from /proc/sys/net/core/wmem_default / 2048 (avg msg size) + sendQueueSize = 256 + sendSlowWarn = (sendQueueSize * 50) / 100 + sendFullWarn = (sendQueueSize * 95) / 100 + writeWaitTime = 30 * time.Second + pongWaitTime = 100 * time.Second + pingInterval = (pongWaitTime * 6) / 10 + authCheckInterval = 5 * time.Second + webConnMemberCacheTime = 1000 * 60 * 30 // 30 minutes + deadQueueSize = 128 // Approximated from /proc/sys/net/core/wmem_default / 2048 (avg msg size) + websocketSuppressWarnThreshold = time.Minute ) const ( @@ -112,6 +113,13 @@ type WebConn struct { endWritePump chan struct{} pumpFinished chan struct{} pluginPosted chan pluginWSPostedHook + + // These counters are to suppress spammy websocket.slow + // and websocket.full logs which happen continuously, if they + // do happen. To improve the situation, we log them only once + // per minute. + lastLogTimeSlow time.Time + lastLogTimeFull time.Time } // CheckConnResult indicates whether a connectionID was present in the hub or not. @@ -215,6 +223,8 @@ func (ps *PlatformService) NewWebConn(cfg *WebConnConfig, suite SuiteIFace, runn endWritePump: make(chan struct{}), pumpFinished: make(chan struct{}), pluginPosted: make(chan pluginWSPostedHook, 10), + lastLogTimeSlow: time.Now(), + lastLogTimeFull: time.Now(), } wc.SetSession(&cfg.Session) @@ -460,7 +470,7 @@ func (wc *WebConn) writePump() { continue } - if len(wc.send) >= sendFullWarn { + if len(wc.send) >= sendFullWarn && time.Since(wc.lastLogTimeFull) > websocketSuppressWarnThreshold { logData := []mlog.Field{ mlog.String("user_id", wc.UserId), mlog.String("type", msg.EventType()), @@ -471,6 +481,7 @@ func (wc *WebConn) writePump() { } mlog.Warn("websocket.full", logData...) + wc.lastLogTimeFull = time.Now() } if evtOk { @@ -711,11 +722,15 @@ func (wc *WebConn) ShouldSendEvent(msg *model.WebSocketEvent) bool { case model.WebsocketEventTyping, model.WebsocketEventStatusChange, model.WebsocketEventChannelViewed: - mlog.Warn( - "websocket.slow: dropping message", - mlog.String("user_id", wc.UserId), - mlog.String("type", msg.EventType()), - ) + if time.Since(wc.lastLogTimeSlow) > websocketSuppressWarnThreshold { + mlog.Warn( + "websocket.slow: dropping message", + mlog.String("user_id", wc.UserId), + mlog.String("type", msg.EventType()), + ) + // Reset timer to now. + wc.lastLogTimeSlow = time.Now() + } return false } } From 6c9ec24fb99e52f3a83d07ddd0b09b4cfd114f55 Mon Sep 17 00:00:00 2001 From: Pantelis Vratsalis Date: Thu, 23 Mar 2023 13:46:56 +0200 Subject: [PATCH 31/46] [MM-50002] catch and log exceptions from missed message listeners --- webapp/platform/client/src/websocket.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/webapp/platform/client/src/websocket.ts b/webapp/platform/client/src/websocket.ts index c88379ec37..b026891933 100644 --- a/webapp/platform/client/src/websocket.ts +++ b/webapp/platform/client/src/websocket.ts @@ -189,9 +189,16 @@ export default class WebSocketClient { console.log('long timeout, or server restart, or sequence number is not found.'); //eslint-disable-line no-console this.missedEventCallback?.(); - this.missedMessageListeners.forEach((listener) => listener()); - - this.serverSequence = 0; + + for (const listener of this.missedMessageListeners) { + try { + listener(); + } catch (e) { + console.log(`missed message listener "${listener.name}" failed: ${e}`); // eslint-disable-line no-console + } + } + + this.serverSequence = 0; } // If it's a fresh connection, we have to set the connectionId regardless. From da7a6825ce1e9e5c6d4065c200f9b226bae50bad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20Mondrag=C3=B3n?= <79058848+julmondragon@users.noreply.github.com> Date: Tue, 28 Mar 2023 10:54:30 -0500 Subject: [PATCH 32/46] MM-50087_Add marketplace button to apps bar (#22653) --- .../channels/plugins/marketplace/helpers.js | 4 +- webapp/channels/src/actions/command.test.js | 3 +- webapp/channels/src/actions/command.ts | 4 +- .../__snapshots__/actions_menu.test.tsx.snap | 4 +- .../actions_menu/actions_menu.test.tsx | 15 +- .../components/actions_menu/actions_menu.tsx | 10 +- .../actions_menu/actions_menu_empty.test.tsx | 1 + .../actions_menu/actions_menu_mobile.test.tsx | 1 + .../src/components/actions_menu/index.ts | 8 + .../__snapshots__/app_bar.test.tsx.snap | 203 +++++++++-------- .../src/components/app_bar/app_bar.scss | 208 ++++++++++-------- .../src/components/app_bar/app_bar.test.tsx | 62 +++++- .../src/components/app_bar/app_bar.tsx | 42 ++-- .../app_bar/app_bar_marketplace.tsx | 60 +++++ .../index.tsx | 1 + .../product_menu_list.test.tsx.snap | 27 ++- .../product_menu_list/product_menu_list.tsx | 5 +- .../marketplace_modal.test.tsx | 16 +- .../plugin_marketplace/marketplace_modal.tsx | 5 +- webapp/channels/src/i18n/en.json | 3 +- webapp/channels/src/sass/utils/_mixins.scss | 43 ++++ 21 files changed, 485 insertions(+), 240 deletions(-) create mode 100644 webapp/channels/src/components/app_bar/app_bar_marketplace.tsx diff --git a/e2e/cypress/tests/integration/channels/plugins/marketplace/helpers.js b/e2e/cypress/tests/integration/channels/plugins/marketplace/helpers.js index 1820015814..b1ce96d0a5 100644 --- a/e2e/cypress/tests/integration/channels/plugins/marketplace/helpers.js +++ b/e2e/cypress/tests/integration/channels/plugins/marketplace/helpers.js @@ -5,10 +5,10 @@ export function verifyPluginMarketplaceVisibility(shouldBeVisible) { cy.uiOpenProductMenu().within(() => { if (shouldBeVisible) { // * Verify Marketplace button should exist - cy.findByText('Marketplace').should('exist'); + cy.findByText('App Marketplace').should('exist'); } else { // * Verify Marketplace button should not exist - cy.findByText('Marketplace').should('not.exist'); + cy.findByText('App Marketplace').should('not.exist'); } }); } diff --git a/webapp/channels/src/actions/command.test.js b/webapp/channels/src/actions/command.test.js index c83037f136..de9a9b01be 100644 --- a/webapp/channels/src/actions/command.test.js +++ b/webapp/channels/src/actions/command.test.js @@ -6,6 +6,7 @@ import {Client4} from 'mattermost-redux/client'; import * as Channels from 'mattermost-redux/selectors/entities/channels'; import * as Teams from 'mattermost-redux/selectors/entities/teams'; +import {Permissions} from 'mattermost-redux/constants'; import {AppCallResponseTypes} from 'mattermost-redux/constants/apps'; import * as GlobalActions from 'actions/global_actions'; @@ -55,7 +56,7 @@ const initialState = { roles: { custom_role: { permissions: [ - 'sysconsole_read_plugins', + Permissions.SYSCONSOLE_WRITE_PLUGINS, ], }, }, diff --git a/webapp/channels/src/actions/command.ts b/webapp/channels/src/actions/command.ts index 255dff4c51..2b89fae193 100644 --- a/webapp/channels/src/actions/command.ts +++ b/webapp/channels/src/actions/command.ts @@ -130,7 +130,7 @@ export function executeCommand(message: string, args: CommandArgs): ActionFunc { return {data: true}; case '/marketplace': // check if user has permissions to access the read plugins - if (!haveICurrentTeamPermission(state, Permissions.SYSCONSOLE_READ_PLUGINS)) { + if (!haveICurrentTeamPermission(state, Permissions.SYSCONSOLE_WRITE_PLUGINS)) { return {error: {message: localizeMessage('marketplace_command.no_permission', 'You do not have the appropriate permissions to access the marketplace.')}}; } @@ -139,7 +139,7 @@ export function executeCommand(message: string, args: CommandArgs): ActionFunc { return {error: {message: localizeMessage('marketplace_command.disabled', 'The marketplace is disabled. Please contact your System Administrator for details.')}}; } - dispatch(openModal({modalId: ModalIdentifiers.PLUGIN_MARKETPLACE, dialogType: MarketplaceModal})); + dispatch(openModal({modalId: ModalIdentifiers.PLUGIN_MARKETPLACE, dialogType: MarketplaceModal, dialogProps: {openedFrom: 'command'}})); return {data: true}; case '/templates': { const workTemplateEnabled = areWorkTemplatesEnabled(state); diff --git a/webapp/channels/src/components/actions_menu/__snapshots__/actions_menu.test.tsx.snap b/webapp/channels/src/components/actions_menu/__snapshots__/actions_menu.test.tsx.snap index 260071f49f..60367b08bf 100644 --- a/webapp/channels/src/components/actions_menu/__snapshots__/actions_menu.test.tsx.snap +++ b/webapp/channels/src/components/actions_menu/__snapshots__/actions_menu.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`components/actions_menu/ActionsMenu has actions - end user - should not show actions and app marketplace 1`] = ` +exports[`components/actions_menu/ActionsMenu has actions - marketplace disabled or user not having SYSCONSOLE_WRITE_PLUGINS - should not show actions and app marketplace 1`] = ` `; -exports[`components/actions_menu/ActionsMenu has actions - sysadmin - should show actions and app marketplace 1`] = ` +exports[`components/actions_menu/ActionsMenu has actions - marketplace enabled and user has SYSCONSOLE_WRITE_PLUGINS - should show actions and app marketplace 1`] = ` { handleDismissTip: jest.fn(), showPulsatingDot: false, location: 'center', + canOpenMarketplace: false, actions: { openModal: jest.fn(), openAppsModal: jest.fn(), @@ -62,27 +63,29 @@ describe('components/actions_menu/ActionsMenu', () => { wrapper.setProps({ pluginMenuItems: dropdownComponents, + canOpenMarketplace: true, }); expect(wrapper.find('#divider_post_post_id_1_marketplace').exists()).toBe(true); }); - test('has actions - sysadmin - should show actions and app marketplace', () => { + test('has actions - marketplace enabled and user has SYSCONSOLE_WRITE_PLUGINS - should show actions and app marketplace', () => { const wrapper = shallowWithIntl( , ); wrapper.setProps({ pluginMenuItems: dropdownComponents, + canOpenMarketplace: true, }); expect(wrapper).toMatchSnapshot(); }); - test('has actions - end user - should not show actions and app marketplace', () => { + test('has actions - marketplace disabled or user not having SYSCONSOLE_WRITE_PLUGINS - should not show actions and app marketplace', () => { const wrapper = shallowWithIntl( , ); wrapper.setProps({ pluginMenuItems: dropdownComponents, - isSysAdmin: false, + canOpenMarketplace: false, }); expect(wrapper).toMatchSnapshot(); }); @@ -91,6 +94,11 @@ describe('components/actions_menu/ActionsMenu', () => { const wrapper = shallowWithIntl( , ); + + wrapper.setProps({ + canOpenMarketplace: true, + }); + expect(wrapper).toMatchSnapshot(); }); @@ -116,6 +124,7 @@ describe('components/actions_menu/ActionsMenu', () => { components: { [PLUGGABLE_COMPONENT]: dropdownComponents, }, + canOpenMarketplace: true, }); expect(wrapper.find('#divider_post_post_id_1_marketplace').exists()).toBe(true); }); diff --git a/webapp/channels/src/components/actions_menu/actions_menu.tsx b/webapp/channels/src/components/actions_menu/actions_menu.tsx index 8a31075676..547aac2da1 100644 --- a/webapp/channels/src/components/actions_menu/actions_menu.tsx +++ b/webapp/channels/src/components/actions_menu/actions_menu.tsx @@ -20,6 +20,7 @@ import Permissions from 'mattermost-redux/constants/permissions'; import {ActionsTutorialTip} from 'components/actions_menu/actions_menu_tutorial_tip'; import {ModalData} from 'types/actions'; import MarketplaceModal from 'components/plugin_marketplace'; +import {OpenedFromType} from 'components/plugin_marketplace/marketplace_modal'; import OverlayTrigger from 'components/overlay_trigger'; import * as PostUtils from 'utils/post_utils'; import * as Utils from 'utils/utils'; @@ -49,6 +50,7 @@ export type Props = { handleDismissTip: () => void; showPulsatingDot?: boolean; showTutorialTip: boolean; + canOpenMarketplace: boolean; /** * Components for overriding provided by plugins @@ -145,9 +147,11 @@ export class ActionMenuClass extends React.PureComponent { } handleOpenMarketplace = (): void => { + const openedFrom: OpenedFromType = 'actions_menu'; const openMarketplaceData = { modalId: ModalIdentifiers.PLUGIN_MARKETPLACE, dialogType: MarketplaceModal, + dialogProps: {openedFrom}, }; this.props.actions.openModal(openMarketplaceData); }; @@ -341,7 +345,7 @@ export class ActionMenuClass extends React.PureComponent { const {formatMessage} = this.props.intl; let marketPlace = null; - if (this.props.isSysAdmin) { + if (this.props.canOpenMarketplace) { marketPlace = ( {this.renderDivider('marketplace')} @@ -363,11 +367,11 @@ export class ActionMenuClass extends React.PureComponent { const hasPluginItems = Boolean(pluginItems?.length); const hasPluginMenuItems = hasPluginItems || hasApps || hasPluggables; - if (!this.props.isSysAdmin && !hasPluginMenuItems) { + if (!this.props.canOpenMarketplace && !hasPluginMenuItems) { return null; } - if (hasPluginItems || hasApps || hasPluggables) { + if (hasPluginMenuItems) { const pluggable = ( { showTutorialTip: false, appsEnabled: false, isSysAdmin: true, + canOpenMarketplace: false, }; const wrapper = shallow( diff --git a/webapp/channels/src/components/actions_menu/actions_menu_mobile.test.tsx b/webapp/channels/src/components/actions_menu/actions_menu_mobile.test.tsx index e712e9bb4b..3f4f3c3534 100644 --- a/webapp/channels/src/components/actions_menu/actions_menu_mobile.test.tsx +++ b/webapp/channels/src/components/actions_menu/actions_menu_mobile.test.tsx @@ -44,6 +44,7 @@ describe('components/actions_menu/ActionsMenu on mobile view', () => { showTutorialTip: false, appsEnabled: false, isSysAdmin: true, + canOpenMarketplace: false, }; const wrapper = shallow( diff --git a/webapp/channels/src/components/actions_menu/index.ts b/webapp/channels/src/components/actions_menu/index.ts index 517aac9fad..21c9c2588b 100644 --- a/webapp/channels/src/components/actions_menu/index.ts +++ b/webapp/channels/src/components/actions_menu/index.ts @@ -26,6 +26,10 @@ import {GlobalState} from 'types/store'; import {openModal} from 'actions/views/modals'; import {makeFetchBindings, postEphemeralCallResponseForPost, handleBindingClick, openAppsModal} from 'actions/apps'; +import {Permissions} from 'mattermost-redux/constants'; +import {isMarketplaceEnabled} from 'mattermost-redux/selectors/entities/general'; +import {haveICurrentTeamPermission} from 'mattermost-redux/selectors/entities/roles'; + import ActionsMenu from './actions_menu'; import {makeGetPostOptionBinding} from './selectors'; @@ -65,6 +69,10 @@ function mapStateToProps(state: GlobalState, ownProps: Props) { pluginMenuItems: state.plugins.components.PostDropdownMenu, teamId: getCurrentTeamId(state), isMobileView: getIsMobileView(state), + canOpenMarketplace: ( + isMarketplaceEnabled(state) && + haveICurrentTeamPermission(state, Permissions.SYSCONSOLE_WRITE_PLUGINS) + ), }; } diff --git a/webapp/channels/src/components/app_bar/__snapshots__/app_bar.test.tsx.snap b/webapp/channels/src/components/app_bar/__snapshots__/app_bar.test.tsx.snap index 0f2403dc6b..528d89c426 100644 --- a/webapp/channels/src/components/app_bar/__snapshots__/app_bar.test.tsx.snap +++ b/webapp/channels/src/components/app_bar/__snapshots__/app_bar.test.tsx.snap @@ -1,63 +1,38 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`components/app_bar/app_bar should match snapshot on mount 1`] = ` -.c0:last-child, -.c0:first-child { - display: none; -} -
- - - - Playbooks Tooltip - - - } - placement="left" - trigger={ - Array [ - "hover", - "focus", - ] + Playbooks Tooltip - + } placement="left" trigger={ @@ -67,77 +42,73 @@ exports[`components/app_bar/app_bar should match snapshot on mount 1`] = ` ] } > -
+ + Playbooks Tooltip + + + } + placement="left" + trigger={ + Array [ + "hover", + "focus", + ] + } >
- fallback_component +
+ fallback_component +
-
+
- -
- <_StyledHr - className="app-bar__divider" - key="divider" - > +
- - - - - Create Subscription - - - } - placement="left" - trigger={ - Array [ - "hover", - "focus", - ] + Create Subscription - + } placement="left" trigger={ @@ -147,25 +118,49 @@ exports[`components/app_bar/app_bar should match snapshot on mount 1`] = ` ] } > -
+ + Create Subscription + + + } + placement="left" + trigger={ + Array [ + "hover", + "focus", + ] + } >
- +
+ +
-
+
- -
+ +
`; diff --git a/webapp/channels/src/components/app_bar/app_bar.scss b/webapp/channels/src/components/app_bar/app_bar.scss index c45afabf44..ce7813b3c9 100644 --- a/webapp/channels/src/components/app_bar/app_bar.scss +++ b/webapp/channels/src/components/app_bar/app_bar.scss @@ -1,6 +1,8 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. +@import 'utils/mixins'; + $app-bar-icon-size: 24px; $app-bar-width: 48px; @@ -10,129 +12,143 @@ $app-bar-width: 48px; display: none; } - position: relative; - width: $app-bar-width; - padding-top: 16px; + display: flex; + min-height: 0; + flex-flow: column; + border-left: solid 1px rgba(var(--center-channel-color-rgb), 0.12); background-color: var(--center-channel-bg); - -ms-overflow-style: none; - overflow-x: hidden; - overflow-y: scroll; - scrollbar-width: none; - text-align: center; - &::before { - position: absolute; - top: 0; - display: block; - width: 100%; - height: 100%; - border-left: solid 1px rgba(var(--center-channel-color-rgb), 0.12); - background-color: rgba(var(--center-channel-color-rgb), 0.04); - content: ''; - } - - .app-bar__icon { + &__top { position: relative; - // Render App Bar icons on top of the RHS background div - //(see `@media screen and (min-width: 769px) > #sidebar-right` in sass/layout/_sidebar-right.scss) - z-index: 21; - width: 100%; - border-left: none; - margin-bottom: 16px; - cursor: pointer; + display: flex; + width: $app-bar-width; + flex: 1; + flex-flow: column; + padding-top: 16px; + background-color: rgba(var(--center-channel-color-rgb), 0.04); + -ms-overflow-style: none; + overflow-x: hidden; + overflow-y: scroll; + scrollbar-width: none; + text-align: center; - &--active { - &::before { - position: absolute; - top: 0; - left: 0; - width: 3px; - height: $app-bar-icon-size; - background-color: var(--sidebar-text-active-border); - border-radius: 0 2px 2px 0; - content: ''; + .app-bar__icon { + position: relative; + // Render App Bar icons on top of the RHS background div + //(see `@media screen and (min-width: 769px) > #sidebar-right` in sass/layout/_sidebar-right.scss) + z-index: 21; + width: 100%; + border-left: none; + margin-bottom: 16px; + cursor: pointer; + + &--active { + &::before { + position: absolute; + top: 0; + left: 0; + width: 3px; + height: $app-bar-icon-size; + background-color: var(--sidebar-text-active-border); + border-radius: 0 2px 2px 0; + content: ''; + } + + .app-bar__icon-inner, + span:not(.pulsating_dot) { + // if we want to show a tourtip/pulsating dot in any of the app bar icons, these styles must be ommitted when span.pulsating_dot + box-shadow: 0 0 0 2px var(--sidebar-text-active-border); + + &:hover { + box-shadow: 0 0 0 2px rgba(var(--sidebar-text-active-border-rgb), 0.92) !important; + } + } } .app-bar__icon-inner, span:not(.pulsating_dot) { - // if we want to show a tourtip/pulsating dot in any of the app bar icons, these styles must be ommitted when span.pulsating_dot - box-shadow: 0 0 0 2px var(--sidebar-text-active-border); - - &:hover { - box-shadow: 0 0 0 2px rgba(var(--sidebar-text-active-border-rgb), 0.92) !important; - } - } - } - - .app-bar__icon-inner, - span:not(.pulsating_dot) { - display: block; - overflow: hidden; - width: $app-bar-icon-size; - height: $app-bar-icon-size; - margin: 0 auto; - border-radius: 50%; - line-height: 1; - - &:hover { - box-shadow: 0 0 0 2px rgba(var(--center-channel-color-rgb), 0.16); - } - - img { + display: block; + overflow: hidden; width: $app-bar-icon-size; height: $app-bar-icon-size; + margin: 0 auto; border-radius: 50%; - } - } + line-height: 1; - span:not(.pulsating_dot) { - padding: 2px; - background-color: white; - fill: var(--button-bg); - font-size: 14px; - line-height: 20px; - vertical-align: middle; + &:hover { + box-shadow: 0 0 0 2px rgba(var(--center-channel-color-rgb), 0.16); + } - &.CompassIcon, - &.icon-brand-zoom { - font-size: 20px; - - &::before { - margin: 0 0 0 0.5px; + img { + width: $app-bar-icon-size; + height: $app-bar-icon-size; + border-radius: 50%; } } - } - .app-bar__old-icon { - color: rgba(var(--center-channel-color-rgb), 0.56); + span:not(.pulsating_dot) { + padding: 2px; + background-color: white; + fill: var(--button-bg); + font-size: 14px; + line-height: 20px; + vertical-align: middle; - &:hover, - &--active { - color: rgba(var(--center-channel-color-rgb), 0.72); + &.CompassIcon, + &.icon-brand-zoom { + font-size: 20px; + + &::before { + margin: 0 0 0 0.5px; + } + } + } + + .app-bar__old-icon { + color: rgba(var(--center-channel-color-rgb), 0.56); + + &:hover, + &--active { + color: rgba(var(--center-channel-color-rgb), 0.72); + } + } + + .app-bar__icon-inner--centered { + display: grid; + place-items: center; } } - .app-bar__icon-inner--centered { - display: grid; - place-items: center; + .app-bar__divider { + width: 28px; + border-top: 1px solid rgba(var(--center-channel-color-rgb), 0.16); + margin-top: 14px; + margin-bottom: 14px; + } + + .app-bar__icon.channel-header__icon--active { + background: rgba(var(--button-bg-rgb), 0.08); + color: var(--button-bg); + fill: var(--button-bg); } } - .app-bar__divider { - width: 28px; - border-top: 1px solid rgba(var(--center-channel-color-rgb), 0.16); - margin-top: 14px; - margin-bottom: 14px; - } + &__bottom { + display: flex; + flex-flow: column; + align-items: center; + padding-top: 24px; + padding-bottom: 36px; + background-color: rgba(var(--center-channel-color-rgb), 0.04); - .app-bar__icon.channel-header__icon--active { - background: rgba(var(--button-bg-rgb), 0.08); - color: var(--button-bg); - fill: var(--button-bg); + .app_bar__marketplace_button { + @include icon-button; + @include icon-button-small-compact; + } } } // This style is defined outside the .app-bar block above because it doesn't seem to work when defined there -.app-bar::-webkit-scrollbar { +.app-bar__top::-webkit-scrollbar { display: none; } diff --git a/webapp/channels/src/components/app_bar/app_bar.test.tsx b/webapp/channels/src/components/app_bar/app_bar.test.tsx index 03598dbf3d..3f8d429853 100644 --- a/webapp/channels/src/components/app_bar/app_bar.test.tsx +++ b/webapp/channels/src/components/app_bar/app_bar.test.tsx @@ -2,7 +2,7 @@ // See LICENSE.txt for license information. import React from 'react'; -import {mount} from 'enzyme'; +import {mount, shallow} from 'enzyme'; import 'jest-styled-components'; import {AppBinding} from '@mattermost/types/apps'; @@ -10,6 +10,7 @@ import {AppBinding} from '@mattermost/types/apps'; import {PluginComponent} from 'types/store/plugins'; import {GlobalState} from 'types/store'; +import {Permissions} from 'mattermost-redux/constants'; import {AppBindingLocations} from 'mattermost-redux/constants/apps'; import AppBar from './app_bar'; @@ -82,6 +83,21 @@ describe('components/app_bar/app_bar', () => { myPreferences: { }, } as any, + users: { + currentUserId: 'user1', + profiles: { + user1: { + roles: 'system_user', + }, + }, + } as any, + roles: { + roles: { + system_user: { + permissions: [], + }, + }, + } as any, }, } as GlobalState; }); @@ -134,4 +150,48 @@ describe('components/app_bar/app_bar', () => { expect(wrapper).toMatchSnapshot(); }); + + test('should not show marketplace if disabled or user does not have SYSCONSOLE_WRITE_PLUGINS permission', async () => { + mockState.entities.general = { + config: { + EnableAppBar: 'true', + FeatureFlagAppsEnabled: 'true', + EnableMarketplace: 'true', + PluginsEnabled: 'true', + }, + } as any; + + const wrapper = shallow( + , + ); + + expect(wrapper.find('AppBarMarketplace').exists()).toEqual(false); + }); + + test('should show marketplace if enabled and user has SYSCONSOLE_WRITE_PLUGINS permission', async () => { + mockState.entities.general = { + config: { + EnableAppBar: 'true', + FeatureFlagAppsEnabled: 'true', + EnableMarketplace: 'true', + PluginsEnabled: 'true', + }, + } as any; + + mockState.entities.roles = { + roles: { + system_user: { + permissions: [ + Permissions.SYSCONSOLE_WRITE_PLUGINS, + ], + }, + }, + } as any; + + const wrapper = shallow( + , + ); + + expect(wrapper.find('AppBarMarketplace').exists()).toEqual(true); + }); }); diff --git a/webapp/channels/src/components/app_bar/app_bar.tsx b/webapp/channels/src/components/app_bar/app_bar.tsx index ec05a5bd19..3ae5815c2a 100644 --- a/webapp/channels/src/components/app_bar/app_bar.tsx +++ b/webapp/channels/src/components/app_bar/app_bar.tsx @@ -12,8 +12,15 @@ import {getAppBarAppBindings} from 'mattermost-redux/selectors/entities/apps'; import {getAppBarPluginComponents, getChannelHeaderPluginComponents, shouldShowAppBar} from 'selectors/plugins'; import {suitePluginIds} from 'utils/constants'; +import {Permissions} from 'mattermost-redux/constants'; +import {isMarketplaceEnabled} from 'mattermost-redux/selectors/entities/general'; +import {haveICurrentTeamPermission} from 'mattermost-redux/selectors/entities/roles'; + +import {GlobalState} from '@mattermost/types/store'; + import AppBarPluginComponent, {isAppBarPluginComponent} from './app_bar_plugin_component'; import AppBarBinding, {isAppBinding} from './app_bar_binding'; +import AppBarMarketplace from './app_bar_marketplace'; import './app_bar.scss'; @@ -24,6 +31,10 @@ export default function AppBar() { const currentProduct = useCurrentProduct(); const currentProductId = useCurrentProductId(); const enabled = useSelector(shouldShowAppBar); + const canOpenMarketplace = useSelector((state: GlobalState) => ( + isMarketplaceEnabled(state) && + haveICurrentTeamPermission(state, Permissions.SYSCONSOLE_WRITE_PLUGINS) + )); if ( !enabled || @@ -40,11 +51,15 @@ export default function AppBar() { const items: ReactNode[] = [ ...coreProductComponents, - divider, + getDivider(coreProductComponents.length, (pluginComponents.length + channelHeaderComponents.length + appBarBindings.length)), ...pluginComponents, ...channelHeaderComponents, ...appBarBindings, ].map((x) => { + if (!x) { + return x; + } + if (isAppBarPluginComponent(x)) { if (!inScope(x.supportedProductIds ?? null, currentProductId, currentProduct?.pluginId)) { return null; @@ -69,26 +84,23 @@ export default function AppBar() { return x; }); - if (!items.some((x) => Boolean(x) && x !== divider)) { - return null; - } - return (
- {items} +
+ {items} +
+ {canOpenMarketplace && ( +
+ +
+ )}
); } -const divider = ( +const getDivider = (beforeCount: number, afterCount: number) => (beforeCount && afterCount ? (
-); +) : null); diff --git a/webapp/channels/src/components/app_bar/app_bar_marketplace.tsx b/webapp/channels/src/components/app_bar/app_bar_marketplace.tsx new file mode 100644 index 0000000000..11b379bd75 --- /dev/null +++ b/webapp/channels/src/components/app_bar/app_bar_marketplace.tsx @@ -0,0 +1,60 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React, {useCallback} from 'react'; +import {useDispatch} from 'react-redux'; +import {useIntl} from 'react-intl'; +import {Tooltip} from 'react-bootstrap'; + +import Icon from '@mattermost/compass-components/foundations/icon'; + +import {openModal} from 'actions/views/modals'; + +import MarketplaceModal from 'components/plugin_marketplace'; +import OverlayTrigger from 'components/overlay_trigger'; + +import {Constants, ModalIdentifiers} from 'utils/constants'; + +const AppBarMarketplace = () => { + const {formatMessage} = useIntl(); + const dispatch = useDispatch(); + + const handleOpenMarketplace = useCallback(() => { + dispatch( + openModal({ + modalId: ModalIdentifiers.PLUGIN_MARKETPLACE, + dialogType: MarketplaceModal, + dialogProps: {openedFrom: 'app_bar'}, + }), + ); + }, [dispatch]); + + const label = formatMessage({id: 'app_bar.marketplace', defaultMessage: 'App Marketplace'}); + + return ( + + {label} + + )} + > + + + ); +}; + +export default AppBarMarketplace; diff --git a/webapp/channels/src/components/custom_open_plugin_install_post_renderer/index.tsx b/webapp/channels/src/components/custom_open_plugin_install_post_renderer/index.tsx index 06020b66c4..d16f073cf1 100644 --- a/webapp/channels/src/components/custom_open_plugin_install_post_renderer/index.tsx +++ b/webapp/channels/src/components/custom_open_plugin_install_post_renderer/index.tsx @@ -301,6 +301,7 @@ export default function OpenPluginInstallPost(props: {post: Post}) { className='color--link' modalId={ModalIdentifiers.PLUGIN_MARKETPLACE} dialogType={MarketplaceModal} + dialogProps={{openedFrom: 'open_plugin_install_post'}} > {text} diff --git a/webapp/channels/src/components/global_header/left_controls/product_menu/product_menu_list/__snapshots__/product_menu_list.test.tsx.snap b/webapp/channels/src/components/global_header/left_controls/product_menu/product_menu_list/__snapshots__/product_menu_list.test.tsx.snap index 94179aca7a..f8ea6848e7 100644 --- a/webapp/channels/src/components/global_header/left_controls/product_menu/product_menu_list/__snapshots__/product_menu_list.test.tsx.snap +++ b/webapp/channels/src/components/global_header/left_controls/product_menu/product_menu_list/__snapshots__/product_menu_list.test.tsx.snap @@ -147,6 +147,11 @@ exports[`components/global/product_switcher_menu should match snapshot with id 1 teamId="" > } id="marketplaceModal" modalId="plugin_marketplace" show={false} - text="Marketplace" + text="App Marketplace" /> } id="marketplaceModal" modalId="plugin_marketplace" show={true} - text="Marketplace" + text="App Marketplace" /> } id="marketplaceModal" modalId="plugin_marketplace" show={false} - text="Marketplace" + text="App Marketplace" /> { modalId={ModalIdentifiers.PLUGIN_MARKETPLACE} show={isMessaging && !isMobile && enablePluginMarketplace} dialogType={MarketplaceModal} - text={formatMessage({id: 'navbar_dropdown.marketplace', defaultMessage: 'Marketplace'})} + dialogProps={{openedFrom: 'product_menu'}} + text={formatMessage({id: 'navbar_dropdown.marketplace', defaultMessage: 'App Marketplace'})} icon={ } /> diff --git a/webapp/channels/src/components/plugin_marketplace/marketplace_modal.test.tsx b/webapp/channels/src/components/plugin_marketplace/marketplace_modal.test.tsx index 4bf24800a9..3e2938603c 100644 --- a/webapp/channels/src/components/plugin_marketplace/marketplace_modal.test.tsx +++ b/webapp/channels/src/components/plugin_marketplace/marketplace_modal.test.tsx @@ -119,6 +119,7 @@ describe('components/marketplace/', () => { pluginStatuses: {}, siteURL: 'http://example.com', firstAdminVisitMarketplaceStatus: false, + openedFrom: 'actions_menu', actions: { closeModal: jest.fn(), fetchListing: jest.fn(() => { @@ -191,8 +192,21 @@ describe('components/marketplace/', () => { wrapper.setState({filter: 'nps'}); wrapper.instance().doSearch(); - expect(trackEvent).toHaveBeenCalledWith('plugins', 'ui_marketplace_opened'); + expect(trackEvent).toHaveBeenCalledWith('plugins', 'ui_marketplace_opened', {from: 'actions_menu'}); expect(trackEvent).toHaveBeenCalledWith('plugins', 'ui_marketplace_search', {filter: 'nps'}); }); + + test('Should call for opened track event on mount', () => { + const openedFrom = 'actions_menu'; + + shallow( + , + ); + + expect(trackEvent).toHaveBeenCalledWith('plugins', 'ui_marketplace_opened', {from: openedFrom}); + }); }); }); diff --git a/webapp/channels/src/components/plugin_marketplace/marketplace_modal.tsx b/webapp/channels/src/components/plugin_marketplace/marketplace_modal.tsx index bc80cde1de..59ac7510ba 100644 --- a/webapp/channels/src/components/plugin_marketplace/marketplace_modal.tsx +++ b/webapp/channels/src/components/plugin_marketplace/marketplace_modal.tsx @@ -31,6 +31,8 @@ const MarketplaceTabs = { const SEARCH_TIMEOUT_MILLISECONDS = 200; +export type OpenedFromType = 'actions_menu' | 'app_bar' | 'channel_header' | 'command' | 'open_plugin_install_post' | 'product_menu'; + type AllListingProps = { listing: Array; }; @@ -97,6 +99,7 @@ export type MarketplaceModalProps = { siteURL: string; pluginStatuses?: Record; firstAdminVisitMarketplaceStatus: boolean; + openedFrom: OpenedFromType; actions: { closeModal: () => void; fetchListing(localOnly?: boolean): Promise<{error?: Error}>; @@ -131,7 +134,7 @@ export default class MarketplaceModal extends React.PureComponent Date: Mon, 27 Mar 2023 16:28:42 +0200 Subject: [PATCH 33/46] Move /e2e -> /e2e-tests --- .github/codeql/codeql-config.yml | 4 +- .github/workflows/channels-ci.yml | 40 +++++++++--------- .../{e2e-ci.yml => e2e-tests-ci.yml} | 10 ++--- .gitignore | 34 +++++++-------- {e2e => e2e-tests}/.gitignore | 0 {e2e => e2e-tests}/cypress/.eslintignore | 0 {e2e => e2e-tests}/cypress/.eslintrc.json | 0 {e2e => e2e-tests}/cypress/Dockerfile.webhook | 0 {e2e => e2e-tests}/cypress/README-Subpath.md | 0 {e2e => e2e-tests}/cypress/cypress.config.ts | 0 .../cypress/generate_test_cycle.js | 0 {e2e => e2e-tests}/cypress/package-lock.json | 0 {e2e => e2e-tests}/cypress/package.json | 0 .../@testing-library+cypress+9.0.0.patch | 0 {e2e => e2e-tests}/cypress/run_test_cycle.js | 0 {e2e => e2e-tests}/cypress/run_tests.js | 0 {e2e => e2e-tests}/cypress/save_report.js | 0 .../Ignore-X-Frame-headers/background.js | 0 .../Ignore-X-Frame-headers/manifest.json | 0 .../tests/fixtures/MM-logo-horizontal.png | Bin .../fixtures/animated-gif-image-file.gif | Bin .../cypress/tests/fixtures/bmp-image-file.bmp | Bin .../tests/fixtures/bot-default-avatar.png | Bin .../tests/fixtures/client_billing.json | 0 .../fixtures/console-example-inputs.json | 0 .../tests/fixtures/date_time_format.js | 0 .../cypress/tests/fixtures/favicon-16x16.png | Bin .../tests/fixtures/favicon-default-16x16.png | Bin .../tests/fixtures/favicon-mentions-16x16.png | Bin .../tests/fixtures/favicon-unread-16x16.png | Bin .../tests/fixtures/gif-image-file-resized.gif | Bin .../cypress/tests/fixtures/gif-image-file.gif | Bin .../tests/fixtures/hooks/message_menus.json | 0 .../hooks/message_menus_with_datasource.json | 0 .../cypress/tests/fixtures/huge-image.jpg | Bin .../cypress/tests/fixtures/image-1000x40.jpg | Bin .../cypress/tests/fixtures/image-1600x40.jpg | Bin .../cypress/tests/fixtures/image-20x20.jpg | Bin .../cypress/tests/fixtures/image-400x40.jpg | Bin .../cypress/tests/fixtures/image-400x400.jpg | Bin .../cypress/tests/fixtures/image-40x400.jpg | Bin .../cypress/tests/fixtures/image-50x50.jpg | Bin .../cypress/tests/fixtures/image-60x60.jpg | Bin .../tests/fixtures/image-small-height.png | Bin .../tests/fixtures/image-small-width.png | Bin .../interactive_message_menus_options.json | 0 .../cypress/tests/fixtures/jpg-image-file.jpg | Bin .../cypress/tests/fixtures/ldap-add-user.ldif | 0 .../tests/fixtures/ldap-reset-data.ldif | 0 .../cypress/tests/fixtures/ldap_users.json | 0 .../cypress/tests/fixtures/long_text_post.txt | 0 .../cypress/tests/fixtures/m4a-audio-file.m4a | Bin .../fixtures/markdown/markdown_basic.html | 0 .../tests/fixtures/markdown/markdown_basic.md | 0 .../markdown/markdown_block_quotes_1.html | 0 .../markdown/markdown_block_quotes_1.md | 0 .../markdown/markdown_block_quotes_2.md | 0 .../markdown/markdown_carriage_return.html | 0 .../markdown/markdown_carriage_return.md | 0 .../markdown_carriage_return_two_lines.html | 0 .../markdown_carriage_return_two_lines.md | 0 .../markdown/markdown_code_block.html | 0 .../fixtures/markdown/markdown_code_block.md | 0 .../markdown/markdown_code_syntax.html | 0 .../markdown/markdown_escape_characters.html | 0 .../markdown/markdown_escape_characters.md | 0 .../fixtures/markdown/markdown_headings.html | 0 .../fixtures/markdown/markdown_headings.md | 0 .../markdown/markdown_inline_code.html | 0 .../fixtures/markdown/markdown_inline_code.md | 0 .../markdown/markdown_inline_images_1.md | 0 .../markdown/markdown_inline_images_2.md | 0 .../markdown/markdown_inline_images_3.md | 0 .../markdown/markdown_inline_images_4.md | 0 .../markdown/markdown_inline_images_5.md | 0 .../markdown/markdown_inline_images_6.md | 0 .../fixtures/markdown/markdown_latex.html | 0 .../tests/fixtures/markdown/markdown_latex.md | 0 .../fixtures/markdown/markdown_lines.html | 0 .../tests/fixtures/markdown/markdown_lines.md | 0 .../fixtures/markdown/markdown_list.html | 0 .../markdown/markdown_not_autolink.html | 0 .../markdown/markdown_not_autolink.md | 0 .../markdown/markdown_not_in_code_block.html | 0 .../markdown/markdown_not_in_code_block.md | 0 .../fixtures/markdown/markdown_postgres.html | 0 .../fixtures/markdown/markdown_postgres.md | 0 .../fixtures/markdown/markdown_python.html | 0 .../fixtures/markdown/markdown_python.md | 0 .../fixtures/markdown/markdown_shell.html | 0 .../tests/fixtures/markdown/markdown_shell.md | 0 .../fixtures/markdown/markdown_tables.html | 0 .../markdown/markdown_test_basic.html | 0 .../markdown/markdown_text_style.html | 0 .../fixtures/markdown/markdown_text_style.md | 0 .../markdown/markdown_typescript.html | 0 .../fixtures/markdown/markdown_typescript.md | 0 .../tests/fixtures/mattermost-icon.png | Bin .../fixtures/mattermost-icon_128x128.png | Bin .../cypress/tests/fixtures/messages.js | 0 .../fixtures/mm_file_testing/Audio/AAC.aac | Bin .../fixtures/mm_file_testing/Audio/FLAC.flac | Bin .../fixtures/mm_file_testing/Audio/M4A.m4a | Bin .../fixtures/mm_file_testing/Audio/M4R.m4r | Bin .../fixtures/mm_file_testing/Audio/MP3.mp3 | Bin .../fixtures/mm_file_testing/Audio/OGG.ogg | Bin .../fixtures/mm_file_testing/Audio/WAV.wav | Bin .../fixtures/mm_file_testing/Audio/WMA.wma | Bin .../tests/fixtures/mm_file_testing/Code/JSON | 0 .../fixtures/mm_file_testing/Code/Patch.diff | 0 .../fixtures/mm_file_testing/Code/Python | 0 .../mm_file_testing/Documents/Excel.xlsx | Bin .../mm_file_testing/Documents/PDF.pdf | Bin .../mm_file_testing/Documents/PPT.pptx | Bin .../mm_file_testing/Documents/Text.txt | 0 .../mm_file_testing/Documents/Word.docx | Bin .../fixtures/mm_file_testing/Images/BMP.bmp | Bin .../fixtures/mm_file_testing/Images/GIF.gif | Bin .../fixtures/mm_file_testing/Images/JPG.jpg | Bin .../fixtures/mm_file_testing/Images/PNG.png | Bin .../fixtures/mm_file_testing/Images/PSD.psd | Bin .../fixtures/mm_file_testing/Images/TIFF.tif | Bin .../fixtures/mm_file_testing/Video/AVI.avi | Bin .../fixtures/mm_file_testing/Video/MKV.mkv | Bin .../fixtures/mm_file_testing/Video/MOV.mov | Bin .../fixtures/mm_file_testing/Video/MP4.mp4 | Bin .../fixtures/mm_file_testing/Video/MPG.mpg | Bin .../fixtures/mm_file_testing/Video/WEBM.webm | Bin .../fixtures/mm_file_testing/Video/WMV.wmv | Bin .../cypress/tests/fixtures/mp3-audio-file.mp3 | Bin .../cypress/tests/fixtures/mp4-video-file.mp4 | Bin .../tests/fixtures/mpeg-video-file.mpg | Bin .../tests/fixtures/playbook-export.json | 0 .../cypress/tests/fixtures/png-image-file.png | Bin .../tests/fixtures/powerpoint-file.ppt | Bin .../tests/fixtures/powerpointx-file.pptx | Bin .../tests/fixtures/saml_ldap_users.json | 0 .../cypress/tests/fixtures/saml_users.json | 0 .../cypress/tests/fixtures/small-image.png | Bin .../cypress/tests/fixtures/svg.svg | 0 .../fixtures/system-roles-console-access.json | 0 .../cypress/tests/fixtures/theme.json | 0 .../tests/fixtures/tiff-image-file.tif | Bin .../cypress/tests/fixtures/timeouts.js | 0 .../tests/fixtures/txt-changed-as-png.png | 0 .../cypress/tests/fixtures/webhook_icon.jpg | Bin .../tests/fixtures/webhook_override_icon.png | Bin .../cypress/tests/fixtures/word-file.doc | Bin .../cypress/tests/fixtures/wordx-file.docx | Bin .../integration/boards/card_badges_spec.ts | 0 .../boards/card_urlproperty_spec.ts | 0 .../integration/boards/create_board_spec.ts | 0 .../boards/group_by_property_spec.ts | 0 .../integration/boards/manage_groups_spec.ts | 0 .../accessibility_account_settings_spec.js | 0 .../accessibility_buttons_spec.js | 0 .../accessibility_dropdowns_spec.js | 0 .../accessibility/accessibility_image_spec.js | 0 .../accessibility_keyboard_usability_spec.js | 0 .../accessibility_nav_diff_regions_spec.js | 0 .../accessibility_popovers_spec.js | 0 .../accessibility/accessibility_post_spec.js | 0 .../accessibility_sidebar_dm_spec.js | 0 .../accessibility_sidebar_spec.ts | 0 .../account_settings/account_settings_spec.ts | 0 .../main_menu_stays_open_spec.ts | 0 .../profile/account_settings_position_spec.ts | 0 .../account_settings/profile/email_spec.ts | 0 .../profile/fullname_edit_spec.ts | 0 .../profile/fullname_truncate_spec.ts | 0 .../profile/help_text_link_spec.ts | 0 .../account_settings/profile/nickname_spec.ts | 0 .../profile/profile_picture_change_spec.ts | 0 .../profile/profile_picture_spec.ts | 0 .../account_settings/profile/username_spec.ts | 0 .../security/access_history_spec.ts | 0 .../security/active_sessions_spec.ts | 0 .../security/password_spec.ts | 0 .../ad_ldap/saml_ldap_sync_id_attrib_spec.js | 0 .../ad_ldap/saml_ldap_sync_remove_spec.js | 0 .../channels/ad_ldap/saml_ldap_sync_spec.js | 0 .../archive_channel_add_reaction_spec.ts | 0 .../archive_channel_header_spec.ts | 0 .../archive_channel_member_spec.ts | 0 .../archive_channel_operations_spec.ts | 0 .../archive_channel_post_spec.ts | 0 .../archive_channel_reaction_spec.ts | 0 .../archive_channel_search_spec.ts | 0 .../archived_channel/archived_channel_spec.ts | 0 .../archived_leave_channel_spec.ts | 0 .../channels/archived_channel/helpers.ts | 0 .../join_archived_channel_spec.ts | 0 .../leave_archived_channel_spec.ts | 0 .../archived_channel/post_menu_spec.ts | 0 .../auth_sso/authentication_1_spec.ts | 0 .../auth_sso/authentication_2_spec.ts | 0 .../auth_sso/authentication_3_spec.ts | 0 .../auth_sso/authentication_4_spec.ts | 0 .../auth_sso/authentication_not_cloud_spec.ts | 0 .../auth_sso/hide_create_account_spec.ts | 0 .../channels/autocomplete/common_test.ts | 0 .../users_in_channel_switcher_spec.js | 0 .../users_in_message_input_box_spec.js | 0 .../autocomplete/database/users_spec.js | 0 .../channels/autocomplete/helpers.ts | 0 .../channels/benchmark/message_spec.ts | 0 .../channels/bot_accounts/bot_api_1_spec.js | 0 .../channels/bot_accounts/bot_api_2_spec.js | 0 .../bot_accounts/bot_api_not_cloud_spec.js | 0 .../bot_accounts/bot_channel_intro_spec.js | 0 .../channels/bot_accounts/create_bot_spec.js | 0 .../bot_accounts/crud_not_cloud_spec.js | 0 .../channels/bot_accounts/crud_spec.js | 0 .../bot_accounts/display_name_spec.js | 0 .../channels/bot_accounts/edit_bot_spec.js | 0 .../bot_accounts/edit_bot_username_spec.js | 0 .../channels/bot_accounts/helpers.js | 0 .../channels/bot_accounts/in_lists_1_spec.js | 0 .../channels/bot_accounts/in_lists_2_spec.js | 0 .../in_teams_and_channels_spec.js | 0 .../managing_bot_accounts_not_cloud_spec.js | 0 .../managing_bot_accounts_spec.js | 0 .../bot_accounts/post_message_spec.js | 0 .../bot_accounts/promote_demote_spec.js | 0 .../bot_accounts/sidebar_display_spec.js | 0 .../channels/bot_accounts/tags_spec.js | 0 .../channel/archived_channels_1_spec.js | 0 .../channel/archived_channels_2_spec.js | 0 .../channels/channel/channel_info_rhs_spec.js | 0 .../channel/channel_members_rhs_spec.js | 0 .../channel_mention_autocomplete_spec.js | 0 .../channel/channel_name_tooltips_spec.js | 0 .../channels/channel/channel_routing_spec.js | 0 .../channels/channel/channel_settings_spec.js | 0 .../channels/channel/channel_switcher_spec.js | 0 .../channel/close_direct_group_spec.js | 0 .../convert_channel_to_private_spec.js | 0 ...ve_and_archive_channel_destructive_spec.ts | 0 .../channels/channel/leave_channel_spec.js | 0 .../channels/channel/more_channels_spec.js | 0 .../channel/more_public_channels_spec.js | 0 .../channel/new_channel_with_board_spec.js | 0 ...pen_rhs_coming_from_system_console_spec.ts | 0 ...updates_manage_channel_members_rhs_spec.js | 0 ...updates_manage_channel_members_rhs_spec.js | 0 .../add_users_to_channel_spec.ts | 0 .../channel_settings/channel_header_spec.ts | 0 .../channel_name_validations_spec.ts | 0 .../more_unreads_position_with_scroll_spec.ts | 0 .../channels/channel_sidebar/category.d.ts | 0 .../category_collapsing_spec.ts | 0 .../channel_sidebar/category_muting_spec.ts | 0 .../category_sorting_1_spec.ts | 0 .../channel_sidebar/category_sorting_spec.ts | 0 .../channel_sidebar/channel_sidebar_spec.ts | 0 .../channel_sidebar/custom_categories_spec.ts | 0 .../channel_sidebar/dm_category_spec.ts | 0 .../channel_sidebar/dm_gm_behaviour_spec.ts | 0 .../dm_gm_filtering_sorting_spec.ts | 0 .../dm_sidebar_not_remove_spec.ts | 0 .../channel_sidebar/drag_and_drop_spec.ts | 0 .../group_unreads_separately_spec.ts | 0 .../channels/channel_sidebar/helpers.ts | 0 .../history_channel_switcher_spec.ts | 0 .../channels/channel_sidebar/hotkeys_spec.ts | 0 .../new_category_badge_spec.ts | 0 .../new_channel_dropdown_spec.ts | 0 .../sidebar_category_menu_spec.ts | 0 .../sidebar_channel_menu_spec.ts | 0 .../channel_sidebar/unread_filter_spec.ts | 0 .../channel_notifications_spec.js | 0 .../crt_settings_spec.js | 0 .../collapsed_reply_threads/crt_tour_spec.js | 0 .../collapsed_reply_threads/files_1_spec.js | 0 .../collapsed_reply_threads/files_spec.js | 0 .../collapsed_reply_threads/following_spec.js | 0 .../global_threads_spec.js | 0 .../last_viewed_spec.js | 0 .../collapsed_reply_threads/replies_spec.js | 0 .../collapsed_reply_threads/unread_spec.js | 0 .../channels/commands/leave_channel_spec.ts | 0 .../custom_status/custom_status_1_spec.ts | 0 .../custom_status/custom_status_2_spec.ts | 0 .../custom_status/custom_status_3_spec.ts | 0 .../custom_status/custom_status_4_spec.ts | 0 .../custom_status/custom_status_5_spec.ts | 0 .../custom_status/custom_status_6_spec.ts | 0 .../custom_status_expiry_1_spec.ts | 0 .../custom_status_expiry_2_spec.ts | 0 .../custom_status_expiry_3_spec.ts | 0 .../custom_status_expiry_4_spec.ts | 0 .../channels/emoji/custom_emoji_1_1_spec.ts | 0 .../channels/emoji/custom_emoji_1_spec.ts | 0 .../channels/emoji/custom_emoji_2_1_spec.ts | 0 .../channels/emoji/custom_emoji_2_spec.ts | 0 .../channels/emoji/custom_emoji_3_spec.ts | 0 .../integration/channels/emoji/helpers.js | 0 .../emoji/recently_used_emoji_1_spec.ts | 0 .../emoji/recently_used_emoji_2_spec.ts | 0 .../channels/emoji/sorted_emojis_spec.ts | 0 .../accessibility_input_fields_spec.js | 0 .../accessibility_modals_dialogs_1_spec.js | 0 .../accessibility_modals_dialogs_spec.js | 0 .../auth_sso/authentication_spec.js | 0 .../auth_sso/mfa_authentication_spec.js | 0 .../managing_bot_accounts_spec.js | 0 .../enterprise/channel/channel_groups_spec.ts | 0 .../cloud/billing/after_subscription_spec.js | 0 .../billing_history_free_trial_spec.ts | 0 .../cloud/billing/cloud_pricing_modal_spec.ts | 0 .../company_information_free_trial_spec.ts | 0 .../billing/downgrade_feedback_modal_spec.ts | 0 .../cloud/billing/notify_admin_spec.ts | 0 .../cloud/billing/payment_free_trial_spec.ts | 0 .../billing/subscriptions_free_trial_spec.ts | 0 .../cloud/billing/yearly_subscription_spec.js | 0 .../channels_spec.js | 0 .../channels_with_special_characters_spec.js | 0 .../helpers/index.js | 0 .../renaming_spec.js | 0 .../renaming_team_spec.js | 0 .../system_console_spec.js | 0 .../users_in_channel_switcher_spec.js | 0 .../users_in_message_input_box_spec.js | 0 .../elasticsearch_autocomplete/users_spec.js | 0 .../email_login_activity_spec.ts | 0 .../not_extended_when_disabled/helpers.js | 0 .../with_email_login_spec.js | 0 .../with_ldap_login_spec.js | 0 .../with_saml_login_spec.js | 0 .../extend_session/session_length_spec.ts | 0 .../group_mentions_permissions_spec.js | 0 .../group_mentions_posts_spec.js | 0 .../group_mentions_system_messages_spec.js | 0 .../enterprise/group_mentions/helpers.js | 0 .../guest_accounts/guest_add_spec.ts | 0 .../guest_experience_ui_spec.ts | 0 .../guest_accounts/guest_feature_spec.ts | 0 .../guest_identification_spec.ts | 0 .../guest_identification_ui_not_cloud_spec.ts | 0 .../guest_identification_ui_spec.ts | 0 .../guest_invitation_ui_more_spec.ts | 0 .../guest_invitation_ui_spec.ts | 0 .../guest_accounts/guest_popover_ui_spec.ts | 0 .../guest_accounts/guest_removal_ui_spec.ts | 0 .../enterprise/guest_accounts/helpers.ts | 0 .../member_invitation_ui_spec.ts | 0 .../system_console_guest_access_ui_spec.ts | 0 ...tem_console_manage_guest_not_cloud_spec.ts | 0 .../system_console_manage_guest_spec.ts | 0 .../integrations/incoming_webhook_spec.js | 0 .../enterprise/ldap/ldap_group_sync_spec.js | 0 .../enterprise/ldap/ldap_guest_spec.js | 0 .../enterprise/ldap/ldap_login_spec.js | 0 .../enterprise/ldap/ldap_setting_spec.js | 0 .../ldap_group/channel_modes_spec.ts | 0 .../ldap_group/group_mentions_spec.ts | 0 .../ldap_group/groups_assign_roles_spec.ts | 0 .../enterprise/ldap_group/invite_bot_spec.ts | 0 .../ldap_group/search_channels_spec.ts | 0 .../team_and_channel_assign_roles_spec.ts | 0 .../channels/enterprise/oauth/oauth_spec.ts | 0 .../permissions/team_permissions_spec.ts | 0 .../profile_popover/profile_popover_spec.ts | 0 .../profile_popover_spec_user_a_b_spec.ts | 0 .../enterprise/saml/okta_login_spec.js | 0 .../enterprise/saml/saml_automated_spec.js | 0 .../enterprise/saml/saml_guest_member_spec.js | 0 .../enterprise/saml/saml_metadata_spec.js | 0 .../self_hosted_pricing_modal_spec.ts | 0 .../self-hosted/self_hosted_purchase_spec.ts | 0 .../about/edition_and_license_spec.js | 0 .../about/starter_edition_spec.js | 0 .../system_console/archived_channels_spec.js | 0 .../authentication_method_spec.js | 0 .../system_console/channel_members_spec.js | 0 .../channel_mentions_spec.js | 0 .../channel_moderation/constants.js | 0 .../channel_moderation/create_posts_spec.js | 0 .../channel_moderation/helpers.js | 0 .../higher_scoped_scheme_spec.js | 0 .../channel_moderation/manage_members_spec.js | 0 .../channel_moderation/post_reactions_spec.js | 0 .../channel_moderation/system_config_spec.js | 0 .../enterprise/system_console/cluster_spec.js | 0 .../compliance_export_multiple_post_spec.js | 0 .../compliance/compliance_export_ui_spec.js | 0 .../data_retention_policies_2_spec.js | 0 .../data_retention_policies_3_spec.js | 0 .../data_retention_policies_4_spec.js | 0 .../data_retention_policies_spec.js | 0 ...ownload_bot_compliance_export_file_spec.js | 0 .../download_compliance_export_file_spec.js | 0 .../system_console/compliance/helpers.js | 0 .../compliance/s3_bucket_storage_spec.js | 0 .../edition_and_license_link_spec.js | 0 .../system_console/environment_spec.js | 0 .../group_configuration_spec.js | 0 .../enterprise/system_console/helpers.js | 0 .../limited_console_access_not_cloud_spec.js | 0 .../limited_console_access_spec.js | 0 .../system_console/main_menu_spec.js | 0 .../system_console/openid/openid_spec.js | 0 .../reporting/site_statistics_spec.js | 0 .../system_console/search_box_spec.js | 0 .../system_console/settings_spec.js | 0 .../sidebar_link_navigation_cloud_spec.js | 0 .../sidebar_link_navigation_e20_spec.js | 0 .../support_packet_generation_spec.js | 0 .../system_scheme_permission_part2_spec.js | 0 .../system_scheme_permission_spec.js | 0 .../system_console/team_guest_channel_spec.js | 0 .../system_console/team_members_spec.js | 0 .../team_scheme_permission_part2_spec.js | 0 .../team_scheme_permission_spec.js | 0 .../ui_and_api/notifications_spec.js | 0 .../enterprise/teams/search_teams_spec.js | 0 .../cancel_file_upload_spec.js | 0 .../channel_files_spec.js | 0 .../cloud_upload_files_spec.js | 0 .../disabled_file_upload_spec.js | 0 .../edit_message_with_attachment_spec.js | 0 .../file_preview_audio_spec.js | 0 .../file_preview_generic_spec.js | 0 .../file_preview_image_spec.js | 0 .../file_preview_video_spec.js | 0 .../channels/files_and_attachments/helpers.js | 0 .../image_link_preview_1_spec.js | 0 .../image_link_preview_new_window_spec.js | 0 .../image_link_preview_spec.js | 0 .../files_and_attachments/paste_image_spec.js | 0 .../upload_files_not_cloud_spec.js | 0 .../upload_files_spec.js | 0 .../youtube_video_spec.js | 0 .../channels/insights/last_viewed_spec.js | 0 .../common_commands_1_spec.js | 0 .../common_commands_2_spec.js | 0 .../common_commands_3_spec.js | 0 .../builtin_commands/groupmsg_command_spec.js | 0 .../integrations/builtin_commands/helper.js | 0 .../builtin_commands/invalid_commands_spec.js | 0 .../builtin_commands/invite_command_spec.js | 0 .../invite_people_command_spec.js | 0 .../user_status_commands_spec.js | 0 .../builtin_commands/user_status_spec.js | 0 .../custom_slash_commands_spec.js | 0 .../custom_slash_commands/helpers.js | 0 .../slash_commands_spec.js | 0 .../attachment_does_not_collapse_spec.ts | 0 .../incoming_webhook/basic_formatting_spec.js | 0 .../cancel_out_of_edit_spec.js | 0 .../incoming_webhook/copy_icon_spec.js | 0 .../delete_incoming_webhook_spec.js | 0 .../description_length_check_spec.js | 0 ...disallow_username_profile_override_spec.js | 0 .../edit_incoming_webhook_spec.js | 0 .../integrations/incoming_webhook/helpers.js | 0 .../inapp_username_profile_override_spec.js | 0 .../incoming_webhook_creates_dm_spec.js | 0 .../incoming_webhook_is_image_only_spec.js | 0 ...ions_display_on_team_where_created_spec.js | 0 .../invalid_attachment_URL_webhook_spec.ts | 0 .../long_url_embedded_image_spec.js | 0 .../incoming_webhook/setting_spec.js | 0 .../setup_incoming_webhook_spec.js | 0 .../incoming_webhook/slack_formatting_spec.js | 0 ..._posts_when_creator_not_in_channel_spec.js | 0 .../integrations/integrations_page_spec.js | 0 ...integrations_search_gives_feedback_spec.js | 0 .../integrations/integrations_spec.js | 0 ...ssage_to_channel_via_slash_command_spec.js | 0 .../delete_outgoing_webhook_spec.js | 0 .../disable_outgoing_webhook_spec.js | 0 .../disable_override_username_profile_spec.js | 0 .../prompt_set_status_spec.js | 0 .../outgoing_webhook/regenerate_token_spec.js | 0 .../search_on_outgoing_webhooks_spec.js | 0 .../outgoing_webhook/token_copy_icon_spec.js | 0 ...plugin_slash_command_stays_visible_spec.js | 0 .../channels/integrations/poll_spec.js | 0 .../channels/integrations/regen_token_spec.js | 0 .../integrations/slash_commands_spec.js | 0 .../interactive_dialog/boolean_spec.js | 0 .../interactive_dialog/demo_boolean_spec.ts | 0 .../interactive_dialog/full_dialog_spec.js | 0 .../interactive_dialog/scrollable_spec.js | 0 .../interactive_dialog/simple_dialog_spec.js | 0 .../interactive_menu/basic_options_spec.js | 0 .../interactive_menu/select_with_keys_spec.js | 0 .../slack_parsing_message_button_spec.js | 0 .../alt_option_plus_up_down_spec.js | 0 .../keyboard_shortcuts/backspace_spec.js | 0 ...cmd_alt_I_toggles_channel_info_rhs_spec.js | 0 .../ctrl_cmd_k_at_username_spec.js | 0 .../ctrl_cmd_k_channel_switch_spec.js | 0 .../ctrl_cmd_k_focuses_message_box_spec.js | 0 ...k_open_channel_from_global_threads_spec.js | 0 .../ctrl_cmd_k_open_gm_with_mouse_spec.js | 0 .../ctrl_cmd_k_unreads_spec.js | 0 .../ctrl_cmd_k_user_from_other_team_spec.js | 0 .../ctrl_cmd_l_set_message_focus_spec.js | 0 .../ctrl_cmd_shift_a_account_settings_spec.js | 0 ..._l_does_not_change_focus_to_msgbox_spec.js | 0 .../ctrl_cmd_shift_m_spec.js | 0 .../ctrl_cmd_shift_slash/helpers.js | 0 .../not_open_emoji_picker_spec.js | 0 .../react_to_center_spec.js | 0 .../ctrl_cmd_shift_slash/react_to_rhs_spec.js | 0 .../ctrl_cmd_up_down_in_rhs_spec.js | 0 .../ctrl_cmd_up_down_no_action_spec.js | 0 .../keyboard_shortcuts/dot_menu_spec.js | 0 .../esc_close_modal_spec.js | 0 .../keyboard_shortcuts_1_spec.js | 0 .../keyboard_shortcuts_2_spec.js | 0 .../keyboard_shortcuts_3_spec.js | 0 .../shift_up_focuses_on_rhs_spec.js | 0 .../system_message_not_open_for_edit_spec.js | 0 .../up_arrow_edit_message_rhs_spec.js | 0 .../up_arrow_edit_message_spec.js | 0 .../large_data_sets/unreads_channels_spec.ts | 0 .../archive_channel_mark_as_unread_spec.js | 0 .../bot_post_mark_as_unread_spec.js | 0 .../mark_as_unread/channel_unread_spec.js | 0 .../channels/mark_as_unread/helpers.js | 0 .../leave_channel_unread_spec.js | 0 .../mark_as_unread/mark_as_unread_spec.js | 0 .../mark_as_unread_using_shortcuts_spec.js | 0 .../mark_dm_post_as_unread_spec.js | 0 .../mark_as_unread/mark_gm_as_unread_spec.js | 0 .../mark_mentions_as_unread_spec.js | 0 .../toast_appears_unread_spec.js | 0 .../mark_as_unread/unread_toast_count_spec.js | 0 .../channels/markdown/markdown_image_spec.js | 0 .../channels/markdown/markdown_text_spec.js | 0 .../channels/menus/main_menu_spec.js | 0 .../channels/menus/status_dropdown_spec.js | 0 .../forward_message_from_dm_spec.js | 0 .../forward_message_from_gm_spec.js | 0 ...rward_message_from_private_channel_spec.js | 0 ...orward_message_from_public_channel_spec.js | 0 .../messaging/at_mentions_user_spec.js | 0 .../autocomplete_shown_each_channel_spec.js | 0 .../channels/messaging/autocomplete_spec.js | 0 .../messaging/autocomplete_with_space_spec.js | 0 .../center_channel_rhs_overlap_spec.js | 0 .../messaging/channel_and_posts_links_spec.js | 0 .../channels/messaging/channel_menu_spec.js | 0 .../channel_read_after_permalink_spec.js | 0 .../channel_users_interactions_spec.js | 0 .../channels/messaging/collapse_link_spec.js | 0 .../messaging/collapsed_message_spec.js | 0 .../channels/messaging/copy_post_text_spec.js | 0 ...trl_cmd_k_find_gm_by_matching_name_spec.js | 0 .../ctrl_cmd_k_open_dm_with_mouse_spec.js | 0 .../channels/messaging/date_separator_spec.js | 0 .../channels/messaging/direct_message_spec.js | 0 .../messaging/dm_list_of_users_spec.js | 0 .../draft_with_only_2_byte_characters_spec.js | 0 .../channels/messaging/edit_message_spec.js | 0 .../emoji_followed_by_punctuation_spec.js | 0 .../channels/messaging/emoji_gender_spec.ts | 0 .../messaging/emoji_insert_position_spec.js | 0 .../messaging/emoji_keyboard_entry_spec.js | 0 .../messaging/emoji_no_overlap_spec.js | 0 .../emoji_picker_keyboard_usability_spec.js | 0 .../messaging/emoji_recently_used_spec.js | 0 .../channels/messaging/emoji_size_spec.js | 0 .../messaging/emoji_skin_tone_spec.js | 0 .../messaging/emoji_to_markdown_spec.js | 0 .../file_upload_in_center_channel_spec.js | 0 .../channels/messaging/focus_move_spec.js | 0 .../channels/messaging/group_message_spec.js | 0 .../messaging/header_not_cloud_spec.js | 0 .../channels/messaging/header_spec.js | 0 .../integration/channels/messaging/helpers.js | 0 .../messaging/image_attachment_spec.js | 0 .../inline_images_open_preview_window_spec.js | 0 ...line_markdown_image_link_open_link_spec.js | 0 .../messaging/input_box_expands_spec.js | 0 .../input_box_expands_with_rhs_spec.js | 0 .../messaging/invalid_emojis_as_text_spec.js | 0 .../messaging/local_date_time_spec.js | 0 .../channels/messaging/long_draft_spec.js | 0 .../messaging/long_post_attachments_spec.js | 0 .../markdown_preview_inline_image_spec.js | 0 .../markdown_quotation_paragraphs_spec.js | 0 .../channels/messaging/markdown_spec.js | 0 .../mention_autocomplete_overlap_spec.js | 0 .../messaging/message_auto_response_spec.js | 0 .../messaging/message_bullets_spec.js | 0 .../message_by_aeroplane_icon_spec.js | 0 .../messaging/message_channel_draw_spec.js | 0 .../message_channel_reference_spec.js | 0 .../message_deleted_on_reply_spec.js | 0 .../messaging/message_deletion_spec.js | 0 .../message_draft_persistance_spec.js | 0 .../channels/messaging/message_draft_spec.js | 0 .../message_draft_then_switch_channel_spec.js | 0 ...ith_attachment_then_switch_channel_spec.js | 0 .../message_edit_post_clear_text_spec.js | 0 .../message_edit_post_history_spec.ts | 0 .../message_edit_post_with_attachment_spec.js | 0 .../messaging/message_emoji_jumbo_spec.js | 0 .../messaging/message_ephemeral_spec.js | 0 .../message_in_another_language_spec.js | 0 .../channels/messaging/message_parse_spec.js | 0 .../messaging/message_permalink_spec.js | 0 .../message_pinning_unpinning_spec.js | 0 .../messaging/message_reaction_gm_spec.js | 0 .../messaging/message_reaction_spec.js | 0 .../messaging/message_reply_bot_post_spec.js | 0 .../messaging/message_reply_gm_spec.js | 0 .../message_reply_input_box_expand_spec.js | 0 .../messaging/message_reply_part2_spec.js | 0 .../message_reply_scrollable_spec.js | 0 .../channels/messaging/message_reply_spec.js | 0 .../messaging/message_reply_too_long_spec.js | 0 .../messaging/message_shortlinking_spec.js | 0 .../channels/messaging/message_spec.js | 0 .../messaging/message_with_gif_spec.js | 0 .../messaging/mobile_message_deletion_spec.js | 0 .../messaging/mobile_profile_popover_spec.js | 0 .../no_matches_for_autocomplete_spec.js | 0 .../messaging/permalink_click_spec.js | 0 .../permalink_loading_indicator_spec.js | 0 .../messaging/permalink_message_edit_spec.js | 0 .../messaging/pinned_parent_post_spec.js | 0 .../channels/messaging/pinned_posts_1_spec.js | 0 .../channels/messaging/pinned_posts_2_spec.js | 0 .../channels/messaging/post_header_spec.js | 0 .../messaging/post_html_table_spec.js | 0 .../messaging/post_options_menu_spec.js | 0 .../messaging/post_pre_header_spec.js | 0 .../messaging/post_textbox_height_spec.js | 0 .../messaging/private_channel_open_spec.js | 0 .../channels/messaging/quick_send_spec.js | 0 .../channels/messaging/quote_notation_spec.js | 0 .../channels/messaging/reactions_spec.js | 0 ...eceive_message_on_socket_reconnect_spec.js | 0 .../channels/messaging/remove_gif_spec.js | 0 .../remove_last_post_in_channel_spec.js | 0 .../channels/messaging/save_post_spec.js | 0 .../messaging/scroll_channel_messages_spec.js | 0 .../send_message_via_profile_popover_spec.js | 0 .../messaging/single_image_thumbnail_spec.js | 0 .../channels/messaging/strikethrough_spec.js | 0 .../system_message_limited_options_spec.js | 0 .../channels/messaging/system_message_spec.js | 0 ..._appears_and_scrollable_in_the_rhs_spec.js | 0 .../tooltip_visual_verification_spec.js | 0 ...ips_on_top_nav_channel_icons_posts_spec.js | 0 .../messaging/typing_on_middle_spec.js | 0 ...typing_should_show_up_when_editing_spec.js | 0 .../channels/modals/quick_switcher_spec.js | 0 .../channel_user_count_spec.js | 0 .../check_user_status_spec.js | 0 .../close_current_dm_redirects_spec.js | 0 .../close_gm_via_menu_spec.js | 0 .../dm_more_searching_from_page_spec.js | 0 .../dm_more_show_user_count_spec.js | 0 .../existing_channel_name_spec.js | 0 .../favorite_and_close_spec.js | 0 .../multi_team_and_dm/gm_add_user_spec.js | 0 .../multi_team_and_dm/gm_header_spec.js | 0 .../join_open_team_from_dm_spec.js | 0 .../multi_team_and_dm/max_gm_members_spec.js | 0 .../multi_team_and_dm/multi_team_join_spec.js | 0 .../multi_team_and_dm/multi_team_spec.js | 0 .../send_dm_user_no_team_spec.js | 0 .../multi_team_and_dm/system_message_spec.js | 0 .../town_square_not_marked_as_unread_spec.js | 0 ...ons_list_with_deactivated_triggers_spec.js | 0 .../notifications/at_mentions_spec.js | 0 .../browser_tab_notification_1_spec.js | 0 .../browser_tab_notification_2_spec.js | 0 .../channel_links_show_as_links_spec.js | 0 .../deselect_username_mention_trigger_spec.js | 0 .../desktop_notifications_1_spec.js | 0 .../desktop_notifications_2_spec.js | 0 .../desktop_notifications_3_spec.js | 0 ...rect_messages_do_not_add_indicator_spec.js | 0 .../channels/notifications/helper.js | 0 .../ignore_channel_mentions_spec.js | 0 .../mention_email_notification_spec.js | 0 .../notifications/message_bar_spec.js | 0 .../message_posted_while_scrolled_up_spec.js | 0 ...tification_preferences_do_not_save_spec.js | 0 ...user_posts_reply_while_scrolled_up_spec.js | 0 .../notifications/reply_notifications_spec.js | 0 .../unread_on_public_channel_spec.js | 0 ...th_same_firstname_channel_mentions_spec.js | 0 .../onboarding/existing_email_adress_spec.js | 0 ...validate_pending_email_invitations_spec.js | 0 .../login_page_link_account_creation_spec.js | 0 .../use_team_invite_link_to_sign_up_spec.js | 0 .../performance/channel_switch_spec.js | 0 .../channels/performance/team_switch_spec.js | 0 .../integration/channels/performance/utils.js | 0 .../plugins/demo_plugin/webhook_spec.js | 0 .../integration/channels/plugins/helpers.js | 0 .../channels/plugins/link_tooltip_spec.js | 0 .../disabled_remote_marketplace_spec.js | 0 .../channels/plugins/marketplace/helpers.js | 0 .../invalid_marketplace_url_spec.js | 0 .../not_render_in_main_menu_spec.js | 0 .../marketplace/render_in_main_menu_spec.js | 0 .../channels/plugins/marketplace/ui_spec.js | 0 .../channels/plugins/plugin_buttons_spec.js | 0 .../channels/plugins/plugin_install_spec.js | 0 .../plugins/plugin_startup_fail_spec.js | 0 .../channels/plugins/upgrade_spec.js | 0 .../profile_settings/profile_settings_spec.js | 0 .../channels/scroll/channel_scroll_spec.js | 0 .../scroll/default_images_collapsed_spec.js | 0 .../scroll/deleting_image_scroll_spec.js | 0 .../channels/scroll/deleting_scroll_spec.js | 0 .../channels/scroll/editing_scroll_spec.js | 0 .../channels/scroll/fixed_width_spec.js | 0 .../integration/channels/scroll/helpers.js | 0 .../scroll/image_aspect_ratio_spec.js | 0 .../channels/search/clear_input_spec.js | 0 .../search/cleared_search_term_spec.js | 0 .../channels/search/mobile_search_spec.js | 0 .../post_search_display_not_cloud_spec.js | 0 .../search/post_search_display_spec.js | 0 .../search/results_post_comment_spec.js | 0 .../channels/search/results_post_spec.js | 0 .../search/search_bar_popup_focus_spec.js | 0 .../search/search_group_message_spec.js | 0 .../channels/search/search_user_file_spec.js | 0 .../channels/search/search_user_post_spec.js | 0 .../search_autocomplete/channels_spec.js | 0 .../search_autocomplete/renaming_spec.js | 0 .../search_autocomplete/scroll_spec.js | 0 .../channels/search_filter/after_spec.js | 0 .../channels/search_filter/before_spec.js | 0 .../channels/search_filter/edit_spec.js | 0 .../search_filter/future_date_spec.js | 0 .../channels/search_filter/helpers.js | 0 .../channels/search_filter/input_spec.js | 0 .../channels/search_filter/invalid_spec.js | 0 .../channels/search_filter/mixed_spec.js | 0 .../channels/search_filter/negative_spec.js | 0 .../channels/search_filter/on_spec.js | 0 .../display/channel_display_mode_spec.js | 0 .../display/clock_display_mode_spec.js | 0 ...age_display_mode_colorize_username_spec.js | 0 .../display/message_display_mode_spec.js | 0 .../display/theme/code_theme_colors_spec.js | 0 .../theme/custom_theme_color_picker_spec.js | 0 .../theme/custom_theme_sidebar_styles_spec.js | 0 .../settings/display/theme/save_theme_spec.js | 0 .../display/theme/settings_view_spec.js | 0 .../display/timezone_display_mode_spec.js | 0 .../channel_switcher_not_cloud_spec.js | 0 .../settings/sidebar/channel_switcher_spec.js | 0 .../settings/sidebar/fullname_spec.js | 0 .../authentication_spec.js | 0 .../desktop_session_expire_spec.js | 0 .../forgot_password_spec.js | 0 .../channels/signin_authentication/helpers.js | 0 .../login_close_server_spec.js | 0 .../login_logout_smoke_spec.js | 0 .../login_open_server_spec.js | 0 .../mfa_authentication_spec.js | 0 .../signin_authentication/signup_spec.js | 0 .../slash_commands/autocomplete_spec.js | 0 .../channels/status/status_dnd_1_spec.js | 0 .../subpath/subpath_channel_routing_spec.js | 0 .../subpath/subpath_dm_search_spec.js | 0 .../channels/subpath/subpath_login_spec.js | 0 .../authentication/password_settings_spec.js | 0 .../custom_terms_of_service_spec.js | 0 .../system_console/demoted_user_spec.js | 0 .../system_console/environment_spec.js | 0 .../feature_discovery_cloud_spec.js | 0 .../feature_discovery_not_cloud_spec.js | 0 .../system_console/feature_discovery_spec.js | 0 .../system_console/inactive_users_spec.js | 0 .../lock_teammate_name_display_spec.js | 0 .../channels/system_console/main_menu_spec.js | 0 .../system_console/mobile_settings_spec.js | 0 .../plugin_marketplace_url_spec.js | 0 .../reporting/server_logs_spec.js | 0 .../reporting/site_statistics_spec.js | 0 .../reporting/site_statistics_te_spec.js | 0 .../reporting/team_statistics_spec.js | 0 .../revoke_all_sessions_spec.js | 0 .../search_box_not_cloud_spec.js | 0 .../system_console/session_length_spec.js | 0 .../sidebar_link_navigation_team_spec.js | 0 .../announcement_banner_spec.js | 0 .../site_configuration/customization_spec.js | 0 .../site_configuration/helper.js | 0 .../link_customization_cloud_spec.js | 0 .../link_customization_e20_1_spec.js | 0 .../link_customization_e20_2_spec.js | 0 .../system_console/site_url_config_spec.js | 0 .../support_packet_generation_spec.js | 0 .../system_console/true_up_review_spec.js | 0 .../custom_site_name_description_spec.ts | 0 .../customization_not_cloud_spec.js | 0 .../ui_and_api/customization_spec.js | 0 .../system_console/unsaved_changes_spec.js | 0 .../users_deactivation_1_spec.js | 0 .../users_deactivation_not_cloud_spec.js | 0 .../users_deactivation_spec.js | 0 .../users_reactivation_spec.js | 0 .../user_management/users_spec.js | 0 .../user_management_not_cloud_spec.js | 0 .../system_console/user_management_spec.js | 0 .../system_console/workspace_deletion_spec.js | 0 .../team_settings/archive_team_spec.ts | 0 .../closed_team_invite_by_email_spec.js | 0 ..._invite_with_non_mattermost_domain_spec.js | 0 ...d_team_invite_with_specific_domain_spec.js | 0 .../team_settings/create_a_team_spec.js | 0 .../channels/team_settings/helpers.js | 0 .../invite_members_backdrop_spec.js | 0 .../team_settings/invite_members_spec.js | 0 .../invite_user_to_closed_team_spec.js | 0 ...closed_team_with_not_allowed_email_spec.js | 0 .../team_settings/manage_members_spec.js | 0 .../team_settings/remove_team_icon_spec.js | 0 .../teammates_pagination_spec.js | 0 .../channels/team_settings/teams_spec.js | 0 .../integration/channels/toast/helpers.js | 0 .../channels/toast/new_messages_toast_spec.js | 0 .../channels/toast/permalink_jump_to_spec.js | 0 .../channels/toast/permalink_post_spec.js | 0 .../permalink_post_with_new_message_spec.js | 0 .../integration/channels/toast/toast_spec.js | 0 .../unread_with_bottom_start_toast_spec.js | 0 .../channel_created/new_sidebar_spec.js | 0 .../channel_created/old_sidebar_spec.js | 0 .../websocket/handle_new_post_spec.js | 0 .../websocket/handle_removed_user/helpers.js | 0 .../handle_removed_user/new_sidebar_spec.js | 0 .../playbooks/adminconsole/analytics_spec.js | 0 .../integration/playbooks/api/runs_spec.js | 0 .../playbooks/channels/app_bar_spec.js | 0 .../playbooks/channels/broadcast_spec.js | 0 .../playbooks/channels/channel_header_spec.js | 0 .../channels/general_actions_spec.js | 0 .../channels/playbook_run_actions.js | 0 .../channels/post_type_components_spec.js | 0 .../playbooks/channels/retrospective_spec.js | 0 .../playbooks/channels/rhs/about_spec.js | 0 .../playbooks/channels/rhs/checklist_spec.js | 0 .../playbooks/channels/rhs/header_spec.js | 0 .../playbooks/channels/rhs/home_spec.js | 0 .../playbooks/channels/rhs/list_spec.js | 0 .../channels/rhs/start_run_rhs_spec.js | 0 .../channels/rhs/status_update_spec.js | 0 .../playbooks/channels/rhs/template_spec.js | 0 .../playbooks/channels/rhs/title_spec.js | 0 .../playbooks/channels/rhs_spec.js | 0 .../playbooks/channels/run_dialog_spec.js | 0 .../playbooks/channels/run_spec.js | 0 .../channels/slash_command/commands_spec.js | 0 .../channels/slash_command/info_spec.js | 0 .../channels/slash_command/owner_spec.js | 0 .../channels/slash_command/test_spec.js | 0 .../channels/slash_command/todo_spec.js | 0 .../channels/update_request_post_spec.js | 0 .../integration/playbooks/digest_spec.js | 0 .../tests/integration/playbooks/lhs_spec.js | 0 .../integration/playbooks/navigation_spec.js | 0 .../playbooks/playbooks/access_spec.js | 0 .../playbooks/creation_button_spec.js | 0 .../playbooks/edit/task_actions_spec.js | 0 .../playbooks/playbooks/edit_metrics_spec.js | 0 .../playbooks/playbooks/edit_spec.js | 0 .../playbooks/playbooks/feedback_spec.js | 0 .../playbooks/playbooks/list_spec.js | 0 .../playbooks/playbooks/overview_spec.js | 0 .../playbooks/playbooks/pagination_spec.js | 0 .../playbooks/playbooks/start_run_spec.js | 0 .../playbooks/playbooks/status_update_spec.js | 0 .../integration/playbooks/runs/list_spec.js | 0 .../playbooks/runs/permissions_spec.js | 0 .../playbooks/runs/rdp_general_spec.js | 0 .../playbooks/runs/rdp_main_checklist_spec.js | 0 .../playbooks/runs/rdp_main_finish_spec.js | 0 .../playbooks/runs/rdp_main_header_spec.js | 0 .../playbooks/runs/rdp_main_restore_spec.js | 0 .../runs/rdp_main_retrospective_spec.js | 0 .../runs/rdp_main_statusupdate_spec.js | 0 .../playbooks/runs/rdp_main_summary_spec.js | 0 .../runs/rdp_main_taskactions_spec.js | 0 .../runs/rdp_rhs_participants_spec.js | 0 .../playbooks/runs/rdp_rhs_runinfo_spec.js | 0 .../playbooks/runs/rdp_rhs_spec.js | 0 .../runs/rdp_rhs_statusupdates_spec.js | 0 .../playbooks/runs/taskinbox_spec.js | 0 .../playbooks/tours_spec_ignore_.js | 0 .../cypress/tests/plugins/client_request.js | 0 .../cypress/tests/plugins/db_request.js | 0 .../cypress/tests/plugins/external_request.ts | 0 .../cypress/tests/plugins/file_util.js | 0 .../cypress/tests/plugins/get_pdf_content.js | 0 .../cypress/tests/plugins/get_recent_email.js | 0 .../cypress/tests/plugins/index.js | 0 .../cypress/tests/plugins/keycloak_request.js | 0 .../cypress/tests/plugins/okta_request.js | 0 .../cypress/tests/plugins/post_bot_message.js | 0 .../tests/plugins/post_incoming_webhook.js | 0 .../tests/plugins/post_list_of_messages.js | 0 .../cypress/tests/plugins/post_message_as.js | 0 .../tests/plugins/react_to_message_as.js | 0 .../cypress/tests/plugins/shell.js | 0 .../cypress/tests/plugins/url_health_check.js | 0 .../cypress/tests/support/api/bots.d.ts | 0 .../cypress/tests/support/api/bots.js | 0 .../cypress/tests/support/api/brand.d.ts | 0 .../cypress/tests/support/api/brand.js | 0 .../cypress/tests/support/api/channel.d.ts | 0 .../cypress/tests/support/api/channel.js | 0 .../cypress/tests/support/api/cloud.d.ts | 0 .../cypress/tests/support/api/cloud.js | 0 .../support/api/cloud_default_config.json | 0 .../cypress/tests/support/api/cluster.d.ts | 0 .../cypress/tests/support/api/cluster.js | 0 .../cypress/tests/support/api/common.d.ts | 0 .../cypress/tests/support/api/common.js | 0 .../tests/support/api/data_retention.d.ts | 0 .../tests/support/api/data_retention.js | 0 .../cypress/tests/support/api/helpers.js | 0 .../cypress/tests/support/api/index.js | 0 .../cypress/tests/support/api/keycloak.d.ts | 0 .../cypress/tests/support/api/keycloak.js | 0 .../tests/support/api/keycloak_realm.json | 0 .../cypress/tests/support/api/ldap.d.ts | 0 .../cypress/tests/support/api/ldap.js | 0 .../support/api/on_prem_default_config.json | 0 .../cypress/tests/support/api/playbooks.js | 0 .../cypress/tests/support/api/plugin.d.ts | 0 .../cypress/tests/support/api/plugin.js | 0 .../cypress/tests/support/api/preference.d.ts | 0 .../cypress/tests/support/api/preference.js | 0 .../cypress/tests/support/api/role.d.ts | 0 .../cypress/tests/support/api/role.js | 0 .../cypress/tests/support/api/saml.d.ts | 0 .../cypress/tests/support/api/saml.js | 0 .../cypress/tests/support/api/scheme.d.ts | 0 .../cypress/tests/support/api/scheme.js | 0 .../cypress/tests/support/api/setup.ts | 0 .../cypress/tests/support/api/status.d.ts | 0 .../cypress/tests/support/api/status.js | 0 .../cypress/tests/support/api/system.d.ts | 0 .../cypress/tests/support/api/system.js | 0 .../cypress/tests/support/api/team.d.ts | 0 .../cypress/tests/support/api/team.js | 0 .../cypress/tests/support/api/user.d.ts | 0 .../cypress/tests/support/api/user.js | 0 .../cypress/tests/support/api/webhooks.d.ts | 0 .../cypress/tests/support/api/webhooks.js | 0 .../cypress/tests/support/api_commands.ts | 0 .../cypress/tests/support/assertions.js | 0 .../cypress/tests/support/client-impl.js | 0 .../cypress/tests/support/client.d.ts | 0 .../cypress/tests/support/client.js | 0 .../tests/support/common_login_commands.d.ts | 0 .../tests/support/common_login_commands.js | 0 .../cypress/tests/support/constants.js | 0 .../cypress/tests/support/db_commands.ts | 0 .../cypress/tests/support/email.ts | 0 .../cypress/tests/support/env.ts | 0 .../tests/support/extended_commands.d.ts | 0 .../tests/support/extended_commands.js | 0 .../tests/support/external_commands.d.ts | 0 .../tests/support/external_commands.js | 0 .../cypress/tests/support/fetch_commands.js | 0 .../cypress/tests/support/index.d.ts | 0 .../cypress/tests/support/index.js | 0 .../tests/support/keycloak_commands.d.ts | 0 .../tests/support/keycloak_commands.js | 0 .../cypress/tests/support/ldap_commands.d.ts | 0 .../cypress/tests/support/ldap_commands.js | 0 .../tests/support/ldap_server_commands.d.ts | 0 .../tests/support/ldap_server_commands.js | 0 .../cypress/tests/support/notification.ts | 0 .../cypress/tests/support/okta_commands.js | 0 .../cypress/tests/support/saml_commands.js | 0 .../cypress/tests/support/shell.d.ts | 0 .../cypress/tests/support/shell.js | 0 .../cypress/tests/support/task_commands.ts | 0 .../support/ui/account_settings_modal.d.ts | 0 .../support/ui/account_settings_modal.js | 0 .../tests/support/ui/announcement_bar.d.ts | 0 .../tests/support/ui/announcement_bar.js | 0 .../cypress/tests/support/ui/boards.d.ts | 0 .../cypress/tests/support/ui/boards.js | 0 .../cypress/tests/support/ui/channel.d.ts | 0 .../cypress/tests/support/ui/channel.js | 0 .../tests/support/ui/channel_header.d.ts | 0 .../tests/support/ui/channel_header.js | 0 .../tests/support/ui/channel_sidebar.js | 0 .../tests/support/ui/cloud_billing.d.ts | 0 .../cypress/tests/support/ui/cloud_billing.js | 0 .../cypress/tests/support/ui/common.d.ts | 0 .../cypress/tests/support/ui/common.js | 0 .../tests/support/ui/compliance_export.d.ts | 0 .../tests/support/ui/compliance_export.js | 0 .../tests/support/ui/data_retention.d.ts | 0 .../tests/support/ui/data_retention.js | 0 .../cypress/tests/support/ui/emoji.ts | 0 .../support/ui/extend_testing_library.d.ts | 0 .../support/ui/extend_testing_library.js | 0 .../tests/support/ui/file_preview.d.ts | 0 .../cypress/tests/support/ui/file_preview.js | 0 .../tests/support/ui/global_header.d.ts | 0 .../cypress/tests/support/ui/global_header.js | 0 .../cypress/tests/support/ui/index.js | 0 .../cypress/tests/support/ui/login.d.ts | 0 .../cypress/tests/support/ui/login.js | 0 .../cypress/tests/support/ui/menu.d.ts | 0 .../cypress/tests/support/ui/menu.js | 0 .../cypress/tests/support/ui/mfa.d.ts | 0 .../cypress/tests/support/ui/mfa.js | 0 .../cypress/tests/support/ui/modal.d.ts | 0 .../cypress/tests/support/ui/modal.js | 0 .../cypress/tests/support/ui/playbooks.js | 0 .../cypress/tests/support/ui/post.ts | 0 .../tests/support/ui/post_dropdown_menu.d.ts | 0 .../tests/support/ui/post_dropdown_menu.js | 0 .../cypress/tests/support/ui/search.js | 0 .../cypress/tests/support/ui/sidebar_left.ts | 0 .../tests/support/ui/sidebar_right.d.ts | 0 .../cypress/tests/support/ui/sidebar_right.js | 0 .../tests/support/ui/suggestion_list.d.ts | 0 .../tests/support/ui/suggestion_list.js | 0 .../cypress/tests/support/ui/system.d.ts | 0 .../cypress/tests/support/ui/system.js | 0 .../cypress/tests/support/ui/team.js | 0 .../cypress/tests/support/ui/tooltip.d.ts | 0 .../cypress/tests/support/ui/tooltip.js | 0 .../cypress/tests/support/ui_commands.ts | 0 .../cypress/tests/support/win.d.ts | 0 .../cypress/tests/types/index.ts | 0 .../cypress/tests/utils/admin_console.js | 0 .../cypress/tests/utils/benchmark.js | 0 .../cypress/tests/utils/config.js | 0 .../cypress/tests/utils/constants.js | 0 .../cypress/tests/utils/email.js | 0 .../cypress/tests/utils/file.js | 0 .../cypress/tests/utils/index.js | 0 .../cypress/tests/utils/plugins.js | 0 .../cypress/tests/utils/timezone.js | 0 {e2e => e2e-tests}/cypress/tsconfig.json | 0 {e2e => e2e-tests}/cypress/utils/artifacts.js | 0 {e2e => e2e-tests}/cypress/utils/constants.js | 0 {e2e => e2e-tests}/cypress/utils/dashboard.js | 0 .../cypress/utils/even_distribution.js | 0 .../cypress/utils/even_distribution.test.js | 0 {e2e => e2e-tests}/cypress/utils/file.js | 0 {e2e => e2e-tests}/cypress/utils/report.js | 0 .../cypress/utils/test_cases.js | 0 .../cypress/utils/webhook_utils.js | 0 {e2e => e2e-tests}/cypress/webhook_serve.js | 0 {e2e => e2e-tests}/playwright/.eslintignore | 0 {e2e => e2e-tests}/playwright/.eslintrc.json | 0 {e2e => e2e-tests}/playwright/.percy.yml | 0 {e2e => e2e-tests}/playwright/.prettierignore | 0 .../playwright/.prettierrc.json | 0 {e2e => e2e-tests}/playwright/README.md | 0 {e2e => e2e-tests}/playwright/global_setup.ts | 0 .../playwright/package-lock.json | 0 {e2e => e2e-tests}/playwright/package.json | 0 .../playwright/playwright.config.ts | 0 {e2e => e2e-tests}/playwright/sample.env | 0 .../support/asset/mattermost-icon_128x128.png | Bin .../playwright/support/browser_context.ts | 0 .../playwright/support/constant.ts | 0 {e2e => e2e-tests}/playwright/support/flag.ts | 0 .../playwright/support/server/channel.ts | 0 .../playwright/support/server/client.ts | 0 .../support/server/default_config.ts | 0 .../playwright/support/server/index.ts | 0 .../playwright/support/server/init.ts | 0 .../playwright/support/server/team.ts | 0 .../playwright/support/server/user.ts | 0 .../playwright/support/test_action.ts | 0 .../playwright/support/test_fixture.ts | 0 .../ui/components/boards/create_modal.ts | 0 .../support/ui/components/boards/sidebar.ts | 0 .../support/ui/components/channels/app_bar.ts | 0 .../support/ui/components/channels/header.ts | 0 .../support/ui/components/channels/post.ts | 0 .../ui/components/channels/post_create.ts | 0 .../ui/components/channels/sidebar_right.ts | 0 .../support/ui/components/global_header.ts | 0 .../playwright/support/ui/components/index.ts | 0 .../support/ui/pages/boards_create.ts | 0 .../support/ui/pages/boards_view.ts | 0 .../playwright/support/ui/pages/channels.ts | 0 .../playwright/support/ui/pages/index.ts | 0 .../support/ui/pages/landing_login.ts | 0 .../playwright/support/ui/pages/login.ts | 0 .../playwright/support/ui/pages/signup.ts | 0 {e2e => e2e-tests}/playwright/support/util.ts | 0 .../playwright/support/visual/index.ts | 0 .../playwright/support/visual/percy.ts | 0 {e2e => e2e-tests}/playwright/test.config.ts | 0 .../create_empty_board.spec.ts | 0 .../visual/boards/board_template.spec.ts | 0 .../board-template-chrome-linux.png | Bin .../board-template-firefox-linux.png | Bin .../board-template-ipad-linux.png | Bin .../visual/boards/view_untitled_board.spec.ts | 0 .../view-untitled-board-chrome-linux.png | Bin .../view-untitled-board-firefox-linux.png | Bin .../view-untitled-board-ipad-linux.png | Bin .../visual/channels/intro_channel.spec.ts | 0 ...o-channel-as-regular-user-chrome-linux.png | Bin ...-channel-as-regular-user-firefox-linux.png | Bin ...-to-channel-as-regular-user-ipad-linux.png | Bin ...o-channel-as-regular-user-iphone-linux.png | Bin .../tests/visual/common/landing_page.spec.ts | 0 .../landing-login-chrome-linux.png | Bin .../landing-login-firefox-linux.png | Bin .../landing-login-ipad-linux.png | Bin .../landing-login-iphone-linux.png | Bin .../tests/visual/common/login.spec.ts | 0 .../login-chrome-linux.png | Bin .../login-error-chrome-linux.png | Bin .../login-error-firefox-linux.png | Bin .../login-error-ipad-linux.png | Bin .../login-error-iphone-linux.png | Bin .../login-firefox-linux.png | Bin .../login-ipad-linux.png | Bin .../login-iphone-linux.png | Bin .../tests/visual/common/signup_email.spec.ts | 0 .../signup-email-chrome-linux.png | Bin .../signup-email-error-chrome-linux.png | Bin .../signup-email-error-firefox-linux.png | Bin .../signup-email-error-ipad-linux.png | Bin .../signup-email-error-iphone-linux.png | Bin .../signup-email-firefox-linux.png | Bin .../signup-email-ipad-linux.png | Bin .../signup-email-iphone-linux.png | Bin {e2e => e2e-tests}/playwright/tsconfig.json | 0 1142 files changed, 44 insertions(+), 44 deletions(-) rename .github/workflows/{e2e-ci.yml => e2e-tests-ci.yml} (84%) rename {e2e => e2e-tests}/.gitignore (100%) rename {e2e => e2e-tests}/cypress/.eslintignore (100%) rename {e2e => e2e-tests}/cypress/.eslintrc.json (100%) rename {e2e => e2e-tests}/cypress/Dockerfile.webhook (100%) rename {e2e => e2e-tests}/cypress/README-Subpath.md (100%) rename {e2e => e2e-tests}/cypress/cypress.config.ts (100%) rename {e2e => e2e-tests}/cypress/generate_test_cycle.js (100%) rename {e2e => e2e-tests}/cypress/package-lock.json (100%) rename {e2e => e2e-tests}/cypress/package.json (100%) rename {e2e => e2e-tests}/cypress/patches/@testing-library+cypress+9.0.0.patch (100%) rename {e2e => e2e-tests}/cypress/run_test_cycle.js (100%) rename {e2e => e2e-tests}/cypress/run_tests.js (100%) rename {e2e => e2e-tests}/cypress/save_report.js (100%) rename {e2e => e2e-tests}/cypress/tests/extensions/Ignore-X-Frame-headers/background.js (100%) rename {e2e => e2e-tests}/cypress/tests/extensions/Ignore-X-Frame-headers/manifest.json (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/MM-logo-horizontal.png (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/animated-gif-image-file.gif (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/bmp-image-file.bmp (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/bot-default-avatar.png (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/client_billing.json (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/console-example-inputs.json (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/date_time_format.js (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/favicon-16x16.png (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/favicon-default-16x16.png (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/favicon-mentions-16x16.png (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/favicon-unread-16x16.png (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/gif-image-file-resized.gif (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/gif-image-file.gif (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/hooks/message_menus.json (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/hooks/message_menus_with_datasource.json (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/huge-image.jpg (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/image-1000x40.jpg (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/image-1600x40.jpg (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/image-20x20.jpg (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/image-400x40.jpg (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/image-400x400.jpg (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/image-40x400.jpg (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/image-50x50.jpg (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/image-60x60.jpg (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/image-small-height.png (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/image-small-width.png (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/interactive_message_menus_options.json (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/jpg-image-file.jpg (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/ldap-add-user.ldif (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/ldap-reset-data.ldif (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/ldap_users.json (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/long_text_post.txt (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/m4a-audio-file.m4a (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_basic.html (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_basic.md (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_block_quotes_1.html (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_block_quotes_1.md (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_block_quotes_2.md (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_carriage_return.html (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_carriage_return.md (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_carriage_return_two_lines.html (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_carriage_return_two_lines.md (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_code_block.html (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_code_block.md (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_code_syntax.html (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_escape_characters.html (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_escape_characters.md (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_headings.html (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_headings.md (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_inline_code.html (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_inline_code.md (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_inline_images_1.md (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_inline_images_2.md (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_inline_images_3.md (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_inline_images_4.md (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_inline_images_5.md (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_inline_images_6.md (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_latex.html (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_latex.md (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_lines.html (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_lines.md (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_list.html (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_not_autolink.html (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_not_autolink.md (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_not_in_code_block.html (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_not_in_code_block.md (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_postgres.html (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_postgres.md (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_python.html (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_python.md (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_shell.html (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_shell.md (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_tables.html (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_test_basic.html (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_text_style.html (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_text_style.md (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_typescript.html (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/markdown/markdown_typescript.md (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mattermost-icon.png (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mattermost-icon_128x128.png (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/messages.js (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Audio/AAC.aac (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Audio/FLAC.flac (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Audio/M4A.m4a (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Audio/M4R.m4r (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Audio/MP3.mp3 (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Audio/OGG.ogg (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Audio/WAV.wav (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Audio/WMA.wma (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Code/JSON (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Code/Patch.diff (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Code/Python (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Documents/Excel.xlsx (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Documents/PDF.pdf (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Documents/PPT.pptx (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Documents/Text.txt (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Documents/Word.docx (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Images/BMP.bmp (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Images/GIF.gif (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Images/JPG.jpg (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Images/PNG.png (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Images/PSD.psd (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Images/TIFF.tif (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Video/AVI.avi (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Video/MKV.mkv (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Video/MOV.mov (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Video/MP4.mp4 (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Video/MPG.mpg (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Video/WEBM.webm (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mm_file_testing/Video/WMV.wmv (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mp3-audio-file.mp3 (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mp4-video-file.mp4 (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/mpeg-video-file.mpg (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/playbook-export.json (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/png-image-file.png (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/powerpoint-file.ppt (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/powerpointx-file.pptx (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/saml_ldap_users.json (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/saml_users.json (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/small-image.png (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/svg.svg (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/system-roles-console-access.json (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/theme.json (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/tiff-image-file.tif (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/timeouts.js (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/txt-changed-as-png.png (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/webhook_icon.jpg (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/webhook_override_icon.png (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/word-file.doc (100%) rename {e2e => e2e-tests}/cypress/tests/fixtures/wordx-file.docx (100%) rename {e2e => e2e-tests}/cypress/tests/integration/boards/card_badges_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/boards/card_urlproperty_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/boards/create_board_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/boards/group_by_property_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/boards/manage_groups_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/accessibility/accessibility_account_settings_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/accessibility/accessibility_buttons_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/accessibility/accessibility_dropdowns_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/accessibility/accessibility_image_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/accessibility/accessibility_keyboard_usability_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/accessibility/accessibility_nav_diff_regions_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/accessibility/accessibility_popovers_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/accessibility/accessibility_post_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/accessibility/accessibility_sidebar_dm_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/accessibility/accessibility_sidebar_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/account_settings/account_settings_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/account_settings/main_menu_stays_open_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/account_settings/profile/account_settings_position_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/account_settings/profile/email_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/account_settings/profile/fullname_edit_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/account_settings/profile/fullname_truncate_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/account_settings/profile/help_text_link_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/account_settings/profile/nickname_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/account_settings/profile/profile_picture_change_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/account_settings/profile/profile_picture_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/account_settings/profile/username_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/account_settings/security/access_history_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/account_settings/security/active_sessions_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/account_settings/security/password_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/ad_ldap/saml_ldap_sync_id_attrib_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/ad_ldap/saml_ldap_sync_remove_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/ad_ldap/saml_ldap_sync_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/archived_channel/archive_channel_add_reaction_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/archived_channel/archive_channel_header_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/archived_channel/archive_channel_member_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/archived_channel/archive_channel_operations_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/archived_channel/archive_channel_post_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/archived_channel/archive_channel_reaction_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/archived_channel/archive_channel_search_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/archived_channel/archived_channel_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/archived_channel/archived_leave_channel_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/archived_channel/helpers.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/archived_channel/join_archived_channel_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/archived_channel/leave_archived_channel_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/archived_channel/post_menu_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/auth_sso/authentication_1_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/auth_sso/authentication_2_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/auth_sso/authentication_3_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/auth_sso/authentication_4_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/auth_sso/authentication_not_cloud_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/auth_sso/hide_create_account_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/autocomplete/common_test.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/autocomplete/database/users_in_channel_switcher_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/autocomplete/database/users_in_message_input_box_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/autocomplete/database/users_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/autocomplete/helpers.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/benchmark/message_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/bot_accounts/bot_api_1_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/bot_accounts/bot_api_2_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/bot_accounts/bot_api_not_cloud_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/bot_accounts/bot_channel_intro_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/bot_accounts/create_bot_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/bot_accounts/crud_not_cloud_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/bot_accounts/crud_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/bot_accounts/display_name_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/bot_accounts/edit_bot_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/bot_accounts/edit_bot_username_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/bot_accounts/helpers.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/bot_accounts/in_lists_1_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/bot_accounts/in_lists_2_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/bot_accounts/in_teams_and_channels_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/bot_accounts/managing_bot_accounts_not_cloud_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/bot_accounts/managing_bot_accounts_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/bot_accounts/post_message_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/bot_accounts/promote_demote_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/bot_accounts/sidebar_display_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/bot_accounts/tags_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel/archived_channels_1_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel/archived_channels_2_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel/channel_info_rhs_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel/channel_members_rhs_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel/channel_mention_autocomplete_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel/channel_name_tooltips_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel/channel_routing_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel/channel_settings_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel/channel_switcher_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel/close_direct_group_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel/convert_channel_to_private_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel/leave_and_archive_channel_destructive_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel/leave_channel_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel/more_channels_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel/more_public_channels_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel/new_channel_with_board_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel/open_rhs_coming_from_system_console_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel/user_to_admin_updates_manage_channel_members_rhs_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel/user_to_channel_admin_member_updates_manage_channel_members_rhs_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel_settings/add_users_to_channel_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel_settings/channel_header_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel_settings/channel_name_validations_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel_settings/more_unreads_position_with_scroll_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel_sidebar/category.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel_sidebar/category_collapsing_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel_sidebar/category_muting_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel_sidebar/category_sorting_1_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel_sidebar/category_sorting_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel_sidebar/channel_sidebar_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel_sidebar/custom_categories_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel_sidebar/dm_category_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel_sidebar/dm_gm_behaviour_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel_sidebar/dm_gm_filtering_sorting_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel_sidebar/dm_sidebar_not_remove_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel_sidebar/drag_and_drop_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel_sidebar/group_unreads_separately_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel_sidebar/helpers.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel_sidebar/history_channel_switcher_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel_sidebar/hotkeys_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel_sidebar/new_category_badge_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel_sidebar/new_channel_dropdown_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel_sidebar/sidebar_category_menu_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel_sidebar/sidebar_channel_menu_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/channel_sidebar/unread_filter_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/collapsed_reply_threads/channel_notifications_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/collapsed_reply_threads/crt_settings_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/collapsed_reply_threads/crt_tour_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/collapsed_reply_threads/files_1_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/collapsed_reply_threads/files_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/collapsed_reply_threads/following_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/collapsed_reply_threads/global_threads_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/collapsed_reply_threads/last_viewed_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/collapsed_reply_threads/replies_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/collapsed_reply_threads/unread_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/commands/leave_channel_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/custom_status/custom_status_1_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/custom_status/custom_status_2_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/custom_status/custom_status_3_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/custom_status/custom_status_4_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/custom_status/custom_status_5_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/custom_status/custom_status_6_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/custom_status/custom_status_expiry/custom_status_expiry_1_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/custom_status/custom_status_expiry/custom_status_expiry_2_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/custom_status/custom_status_expiry/custom_status_expiry_3_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/custom_status/custom_status_expiry/custom_status_expiry_4_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/emoji/custom_emoji_1_1_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/emoji/custom_emoji_1_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/emoji/custom_emoji_2_1_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/emoji/custom_emoji_2_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/emoji/custom_emoji_3_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/emoji/helpers.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/emoji/recently_used_emoji_1_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/emoji/recently_used_emoji_2_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/emoji/sorted_emojis_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/accessibility/accessibility_input_fields_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/accessibility/accessibility_modals_dialogs_1_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/accessibility/accessibility_modals_dialogs_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/auth_sso/authentication_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/auth_sso/mfa_authentication_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/bot_accounts/managing_bot_accounts_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/channel/channel_groups_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/cloud/billing/after_subscription_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/cloud/billing/billing_history_free_trial_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/cloud/billing/cloud_pricing_modal_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/cloud/billing/company_information_free_trial_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/cloud/billing/downgrade_feedback_modal_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/cloud/billing/notify_admin_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/cloud/billing/payment_free_trial_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/cloud/billing/subscriptions_free_trial_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/cloud/billing/yearly_subscription_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/channels_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/channels_with_special_characters_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/helpers/index.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/renaming_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/renaming_team_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/system_console_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/users_in_channel_switcher_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/users_in_message_input_box_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/users_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/extend_session/email_login_activity_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/extend_session/not_extended_when_disabled/helpers.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/extend_session/not_extended_when_disabled/with_email_login_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/extend_session/not_extended_when_disabled/with_ldap_login_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/extend_session/not_extended_when_disabled/with_saml_login_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/extend_session/session_length_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/group_mentions/group_mentions_permissions_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/group_mentions/group_mentions_posts_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/group_mentions/group_mentions_system_messages_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/group_mentions/helpers.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/guest_accounts/guest_add_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/guest_accounts/guest_experience_ui_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/guest_accounts/guest_feature_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/guest_accounts/guest_identification_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/guest_accounts/guest_identification_ui_not_cloud_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/guest_accounts/guest_identification_ui_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/guest_accounts/guest_invitation_ui_more_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/guest_accounts/guest_invitation_ui_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/guest_accounts/guest_popover_ui_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/guest_accounts/guest_removal_ui_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/guest_accounts/helpers.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/guest_accounts/member_invitation_ui_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/guest_accounts/system_console_guest_access_ui_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/guest_accounts/system_console_manage_guest_not_cloud_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/guest_accounts/system_console_manage_guest_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/integrations/incoming_webhook_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/ldap/ldap_group_sync_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/ldap/ldap_guest_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/ldap/ldap_login_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/ldap/ldap_setting_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/ldap_group/channel_modes_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/ldap_group/group_mentions_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/ldap_group/groups_assign_roles_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/ldap_group/invite_bot_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/ldap_group/search_channels_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/ldap_group/team_and_channel_assign_roles_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/oauth/oauth_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/permissions/team_permissions_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/profile_popover/profile_popover_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/profile_popover/profile_popover_spec_user_a_b_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/saml/okta_login_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/saml/saml_automated_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/saml/saml_guest_member_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/saml/saml_metadata_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/self-hosted/self_hosted_pricing_modal_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/self-hosted/self_hosted_purchase_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/about/edition_and_license_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/about/starter_edition_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/archived_channels_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/authentication_method_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/channel_members_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/channel_mentions_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/constants.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/create_posts_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/helpers.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/higher_scoped_scheme_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/manage_members_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/post_reactions_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/system_config_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/cluster_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/compliance/compliance_export_multiple_post_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/compliance/compliance_export_ui_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/compliance/data_retention_policies_2_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/compliance/data_retention_policies_3_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/compliance/data_retention_policies_4_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/compliance/data_retention_policies_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/compliance/download_bot_compliance_export_file_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/compliance/download_compliance_export_file_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/compliance/helpers.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/compliance/s3_bucket_storage_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/edition_and_license_link_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/environment_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/group_configuration_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/helpers.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/limited_console_access_not_cloud_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/limited_console_access_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/main_menu_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/openid/openid_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/reporting/site_statistics_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/search_box_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/settings_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/sidebar_link_navigation_cloud_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/sidebar_link_navigation_e20_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/support_packet_generation_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/system_scheme_permission_part2_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/system_scheme_permission_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/team_guest_channel_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/team_members_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/team_scheme_permission_part2_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/team_scheme_permission_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/system_console/ui_and_api/notifications_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/enterprise/teams/search_teams_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/files_and_attachments/cancel_file_upload_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/files_and_attachments/channel_files_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/files_and_attachments/cloud_upload_files_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/files_and_attachments/disabled_file_upload_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/files_and_attachments/edit_message_with_attachment_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/files_and_attachments/file_preview_audio_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/files_and_attachments/file_preview_generic_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/files_and_attachments/file_preview_image_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/files_and_attachments/file_preview_video_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/files_and_attachments/helpers.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/files_and_attachments/image_link_preview_1_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/files_and_attachments/image_link_preview_new_window_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/files_and_attachments/image_link_preview_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/files_and_attachments/paste_image_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/files_and_attachments/upload_files_not_cloud_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/files_and_attachments/upload_files_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/files_and_attachments/youtube_video_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/insights/last_viewed_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/builtin_commands/common_commands_1_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/builtin_commands/common_commands_2_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/builtin_commands/common_commands_3_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/builtin_commands/groupmsg_command_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/builtin_commands/helper.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/builtin_commands/invalid_commands_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/builtin_commands/invite_command_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/builtin_commands/invite_people_command_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/builtin_commands/user_status_commands_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/builtin_commands/user_status_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/custom_slash_commands/custom_slash_commands_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/custom_slash_commands/helpers.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/custom_slash_commands/slash_commands_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/incoming_webhook/attachment_does_not_collapse_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/incoming_webhook/basic_formatting_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/incoming_webhook/cancel_out_of_edit_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/incoming_webhook/copy_icon_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/incoming_webhook/delete_incoming_webhook_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/incoming_webhook/description_length_check_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/incoming_webhook/disallow_username_profile_override_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/incoming_webhook/edit_incoming_webhook_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/incoming_webhook/helpers.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/incoming_webhook/inapp_username_profile_override_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/incoming_webhook/incoming_webhook_creates_dm_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/incoming_webhook/incoming_webhook_is_image_only_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/incoming_webhook/integrations_display_on_team_where_created_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/incoming_webhook/invalid_attachment_URL_webhook_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/incoming_webhook/long_url_embedded_image_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/incoming_webhook/setting_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/incoming_webhook/setup_incoming_webhook_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/incoming_webhook/slack_formatting_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/incoming_webhook/webhook_posts_when_creator_not_in_channel_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/integrations_page_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/integrations_search_gives_feedback_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/integrations_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/message_to_channel_via_slash_command_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/outgoing_webhook/delete_outgoing_webhook_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/outgoing_webhook/disable_outgoing_webhook_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/outgoing_webhook/disable_override_username_profile_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/outgoing_webhook/prompt_set_status_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/outgoing_webhook/regenerate_token_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/outgoing_webhook/search_on_outgoing_webhooks_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/outgoing_webhook/token_copy_icon_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/plugin_slash_command_stays_visible_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/poll_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/regen_token_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/integrations/slash_commands_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/interactive_dialog/boolean_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/interactive_dialog/demo_boolean_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/interactive_dialog/full_dialog_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/interactive_dialog/scrollable_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/interactive_dialog/simple_dialog_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/interactive_menu/basic_options_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/interactive_menu/select_with_keys_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/interactive_menu/slack_parsing_message_button_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/alt_option_plus_up_down_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/backspace_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_alt_I_toggles_channel_info_rhs_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_at_username_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_channel_switch_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_focuses_message_box_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_open_channel_from_global_threads_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_open_gm_with_mouse_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_unreads_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_user_from_other_team_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_l_set_message_focus_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_a_account_settings_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_l_does_not_change_focus_to_msgbox_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_m_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_slash/helpers.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_slash/not_open_emoji_picker_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_slash/react_to_center_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_slash/react_to_rhs_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_up_down_in_rhs_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_up_down_no_action_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/dot_menu_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/esc_close_modal_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/keyboard_shortcuts_1_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/keyboard_shortcuts_2_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/keyboard_shortcuts_3_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/shift_up_focuses_on_rhs_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/system_message_not_open_for_edit_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/up_arrow_edit_message_rhs_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/keyboard_shortcuts/up_arrow_edit_message_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/large_data_sets/unreads_channels_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/mark_as_unread/archive_channel_mark_as_unread_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/mark_as_unread/bot_post_mark_as_unread_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/mark_as_unread/channel_unread_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/mark_as_unread/helpers.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/mark_as_unread/leave_channel_unread_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/mark_as_unread/mark_as_unread_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/mark_as_unread/mark_as_unread_using_shortcuts_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/mark_as_unread/mark_dm_post_as_unread_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/mark_as_unread/mark_gm_as_unread_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/mark_as_unread/mark_mentions_as_unread_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/mark_as_unread/toast_appears_unread_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/mark_as_unread/unread_toast_count_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/markdown/markdown_image_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/markdown/markdown_text_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/menus/main_menu_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/menus/status_dropdown_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/message_forwarding/forward_message_from_dm_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/message_forwarding/forward_message_from_gm_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/message_forwarding/forward_message_from_private_channel_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/message_forwarding/forward_message_from_public_channel_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/at_mentions_user_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/autocomplete_shown_each_channel_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/autocomplete_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/autocomplete_with_space_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/center_channel_rhs_overlap_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/channel_and_posts_links_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/channel_menu_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/channel_read_after_permalink_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/channel_users_interactions_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/collapse_link_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/collapsed_message_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/copy_post_text_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/ctrl_cmd_k_find_gm_by_matching_name_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/ctrl_cmd_k_open_dm_with_mouse_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/date_separator_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/direct_message_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/dm_list_of_users_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/draft_with_only_2_byte_characters_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/edit_message_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/emoji_followed_by_punctuation_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/emoji_gender_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/emoji_insert_position_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/emoji_keyboard_entry_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/emoji_no_overlap_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/emoji_picker_keyboard_usability_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/emoji_recently_used_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/emoji_size_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/emoji_skin_tone_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/emoji_to_markdown_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/file_upload_in_center_channel_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/focus_move_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/group_message_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/header_not_cloud_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/header_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/helpers.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/image_attachment_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/inline_images_open_preview_window_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/inline_markdown_image_link_open_link_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/input_box_expands_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/input_box_expands_with_rhs_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/invalid_emojis_as_text_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/local_date_time_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/long_draft_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/long_post_attachments_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/markdown_preview_inline_image_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/markdown_quotation_paragraphs_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/markdown_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/mention_autocomplete_overlap_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_auto_response_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_bullets_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_by_aeroplane_icon_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_channel_draw_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_channel_reference_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_deleted_on_reply_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_deletion_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_draft_persistance_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_draft_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_draft_then_switch_channel_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_draft_with_attachment_then_switch_channel_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_edit_post_clear_text_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_edit_post_history_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_edit_post_with_attachment_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_emoji_jumbo_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_ephemeral_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_in_another_language_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_parse_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_permalink_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_pinning_unpinning_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_reaction_gm_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_reaction_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_reply_bot_post_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_reply_gm_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_reply_input_box_expand_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_reply_part2_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_reply_scrollable_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_reply_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_reply_too_long_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_shortlinking_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/message_with_gif_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/mobile_message_deletion_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/mobile_profile_popover_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/no_matches_for_autocomplete_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/permalink_click_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/permalink_loading_indicator_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/permalink_message_edit_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/pinned_parent_post_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/pinned_posts_1_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/pinned_posts_2_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/post_header_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/post_html_table_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/post_options_menu_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/post_pre_header_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/post_textbox_height_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/private_channel_open_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/quick_send_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/quote_notation_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/reactions_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/receive_message_on_socket_reconnect_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/remove_gif_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/remove_last_post_in_channel_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/save_post_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/scroll_channel_messages_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/send_message_via_profile_popover_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/single_image_thumbnail_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/strikethrough_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/system_message_limited_options_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/system_message_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/thread_appears_and_scrollable_in_the_rhs_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/tooltip_visual_verification_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/tooltips_on_top_nav_channel_icons_posts_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/typing_on_middle_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/messaging/typing_should_show_up_when_editing_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/modals/quick_switcher_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/multi_team_and_dm/channel_user_count_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/multi_team_and_dm/check_user_status_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/multi_team_and_dm/close_current_dm_redirects_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/multi_team_and_dm/close_gm_via_menu_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/multi_team_and_dm/dm_more_searching_from_page_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/multi_team_and_dm/dm_more_show_user_count_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/multi_team_and_dm/existing_channel_name_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/multi_team_and_dm/favorite_and_close_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/multi_team_and_dm/gm_add_user_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/multi_team_and_dm/gm_header_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/multi_team_and_dm/join_open_team_from_dm_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/multi_team_and_dm/max_gm_members_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/multi_team_and_dm/multi_team_join_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/multi_team_and_dm/multi_team_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/multi_team_and_dm/send_dm_user_no_team_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/multi_team_and_dm/system_message_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/multi_team_and_dm/town_square_not_marked_as_unread_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/notifications/at_icon_still_shows_mentions_list_with_deactivated_triggers_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/notifications/at_mentions_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/notifications/browser_tab_notification_1_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/notifications/browser_tab_notification_2_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/notifications/channel_links_show_as_links_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/notifications/deselect_username_mention_trigger_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/notifications/desktop_notifications_1_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/notifications/desktop_notifications_2_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/notifications/desktop_notifications_3_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/notifications/direct_messages_do_not_add_indicator_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/notifications/helper.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/notifications/ignore_channel_mentions_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/notifications/mention_email_notification_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/notifications/message_bar_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/notifications/message_posted_while_scrolled_up_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/notifications/notification_preferences_do_not_save_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/notifications/own_user_posts_reply_while_scrolled_up_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/notifications/reply_notifications_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/notifications/unread_on_public_channel_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/notifications/users_with_same_firstname_channel_mentions_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/onboarding/existing_email_adress_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/onboarding/invalidate_pending_email_invitations_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/onboarding/login_page_link_account_creation_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/onboarding/use_team_invite_link_to_sign_up_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/performance/channel_switch_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/performance/team_switch_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/performance/utils.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/plugins/demo_plugin/webhook_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/plugins/helpers.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/plugins/link_tooltip_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/plugins/marketplace/disabled_remote_marketplace_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/plugins/marketplace/helpers.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/plugins/marketplace/invalid_marketplace_url_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/plugins/marketplace/not_render_in_main_menu_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/plugins/marketplace/render_in_main_menu_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/plugins/marketplace/ui_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/plugins/plugin_buttons_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/plugins/plugin_install_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/plugins/plugin_startup_fail_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/plugins/upgrade_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/profile_settings/profile_settings_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/scroll/channel_scroll_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/scroll/default_images_collapsed_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/scroll/deleting_image_scroll_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/scroll/deleting_scroll_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/scroll/editing_scroll_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/scroll/fixed_width_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/scroll/helpers.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/scroll/image_aspect_ratio_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/search/clear_input_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/search/cleared_search_term_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/search/mobile_search_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/search/post_search_display_not_cloud_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/search/post_search_display_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/search/results_post_comment_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/search/results_post_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/search/search_bar_popup_focus_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/search/search_group_message_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/search/search_user_file_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/search/search_user_post_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/search_autocomplete/channels_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/search_autocomplete/renaming_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/search_autocomplete/scroll_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/search_filter/after_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/search_filter/before_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/search_filter/edit_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/search_filter/future_date_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/search_filter/helpers.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/search_filter/input_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/search_filter/invalid_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/search_filter/mixed_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/search_filter/negative_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/search_filter/on_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/settings/display/channel_display_mode_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/settings/display/clock_display_mode_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/settings/display/message_display_mode_colorize_username_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/settings/display/message_display_mode_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/settings/display/theme/code_theme_colors_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/settings/display/theme/custom_theme_color_picker_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/settings/display/theme/custom_theme_sidebar_styles_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/settings/display/theme/save_theme_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/settings/display/theme/settings_view_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/settings/display/timezone_display_mode_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/settings/sidebar/channel_switcher_not_cloud_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/settings/sidebar/channel_switcher_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/settings/sidebar/fullname_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/signin_authentication/authentication_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/signin_authentication/desktop_session_expire_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/signin_authentication/forgot_password_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/signin_authentication/helpers.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/signin_authentication/login_close_server_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/signin_authentication/login_logout_smoke_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/signin_authentication/login_open_server_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/signin_authentication/mfa_authentication_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/signin_authentication/signup_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/slash_commands/autocomplete_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/status/status_dnd_1_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/subpath/subpath_channel_routing_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/subpath/subpath_dm_search_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/subpath/subpath_login_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/authentication/password_settings_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/compliance/custom_terms_of_service_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/demoted_user_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/environment_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/feature_discovery_cloud_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/feature_discovery_not_cloud_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/feature_discovery_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/inactive_users_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/lock_teammate_name_display_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/main_menu_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/mobile_settings_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/plugin_marketplace_url_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/reporting/server_logs_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/reporting/site_statistics_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/reporting/site_statistics_te_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/reporting/team_statistics_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/revoke_all_sessions_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/search_box_not_cloud_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/session_length_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/sidebar_link_navigation_team_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/site_configuration/announcement_banner_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/site_configuration/customization_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/site_configuration/helper.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/site_configuration/link_customization_cloud_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/site_configuration/link_customization_e20_1_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/site_configuration/link_customization_e20_2_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/site_url_config_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/support_packet_generation_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/true_up_review_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/ui_and_api/custom_site_name_description_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/ui_and_api/customization_not_cloud_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/ui_and_api/customization_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/unsaved_changes_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/user_management/users_deactivation_1_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/user_management/users_deactivation_not_cloud_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/user_management/users_deactivation_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/user_management/users_reactivation_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/user_management/users_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/user_management_not_cloud_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/user_management_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/system_console/workspace_deletion_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/team_settings/archive_team_spec.ts (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/team_settings/closed_team_invite_by_email_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/team_settings/closed_team_invite_with_non_mattermost_domain_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/team_settings/closed_team_invite_with_specific_domain_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/team_settings/create_a_team_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/team_settings/helpers.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/team_settings/invite_members_backdrop_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/team_settings/invite_members_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/team_settings/invite_user_to_closed_team_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/team_settings/join_closed_team_with_not_allowed_email_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/team_settings/manage_members_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/team_settings/remove_team_icon_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/team_settings/teammates_pagination_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/team_settings/teams_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/toast/helpers.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/toast/new_messages_toast_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/toast/permalink_jump_to_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/toast/permalink_post_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/toast/permalink_post_with_new_message_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/toast/toast_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/toast/unread_with_bottom_start_toast_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/websocket/channel_created/new_sidebar_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/websocket/channel_created/old_sidebar_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/websocket/handle_new_post_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/websocket/handle_removed_user/helpers.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/channels/websocket/handle_removed_user/new_sidebar_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/adminconsole/analytics_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/api/runs_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/channels/app_bar_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/channels/broadcast_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/channels/channel_header_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/channels/general_actions_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/channels/playbook_run_actions.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/channels/post_type_components_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/channels/retrospective_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/channels/rhs/about_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/channels/rhs/checklist_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/channels/rhs/header_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/channels/rhs/home_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/channels/rhs/list_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/channels/rhs/start_run_rhs_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/channels/rhs/status_update_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/channels/rhs/template_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/channels/rhs/title_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/channels/rhs_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/channels/run_dialog_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/channels/run_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/channels/slash_command/commands_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/channels/slash_command/info_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/channels/slash_command/owner_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/channels/slash_command/test_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/channels/slash_command/todo_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/channels/update_request_post_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/digest_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/lhs_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/navigation_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/playbooks/access_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/playbooks/creation_button_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/playbooks/edit/task_actions_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/playbooks/edit_metrics_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/playbooks/edit_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/playbooks/feedback_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/playbooks/list_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/playbooks/overview_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/playbooks/pagination_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/playbooks/start_run_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/playbooks/status_update_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/runs/list_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/runs/permissions_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/runs/rdp_general_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/runs/rdp_main_checklist_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/runs/rdp_main_finish_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/runs/rdp_main_header_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/runs/rdp_main_restore_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/runs/rdp_main_retrospective_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/runs/rdp_main_statusupdate_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/runs/rdp_main_summary_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/runs/rdp_main_taskactions_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/runs/rdp_rhs_participants_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/runs/rdp_rhs_runinfo_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/runs/rdp_rhs_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/runs/rdp_rhs_statusupdates_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/runs/taskinbox_spec.js (100%) rename {e2e => e2e-tests}/cypress/tests/integration/playbooks/tours_spec_ignore_.js (100%) rename {e2e => e2e-tests}/cypress/tests/plugins/client_request.js (100%) rename {e2e => e2e-tests}/cypress/tests/plugins/db_request.js (100%) rename {e2e => e2e-tests}/cypress/tests/plugins/external_request.ts (100%) rename {e2e => e2e-tests}/cypress/tests/plugins/file_util.js (100%) rename {e2e => e2e-tests}/cypress/tests/plugins/get_pdf_content.js (100%) rename {e2e => e2e-tests}/cypress/tests/plugins/get_recent_email.js (100%) rename {e2e => e2e-tests}/cypress/tests/plugins/index.js (100%) rename {e2e => e2e-tests}/cypress/tests/plugins/keycloak_request.js (100%) rename {e2e => e2e-tests}/cypress/tests/plugins/okta_request.js (100%) rename {e2e => e2e-tests}/cypress/tests/plugins/post_bot_message.js (100%) rename {e2e => e2e-tests}/cypress/tests/plugins/post_incoming_webhook.js (100%) rename {e2e => e2e-tests}/cypress/tests/plugins/post_list_of_messages.js (100%) rename {e2e => e2e-tests}/cypress/tests/plugins/post_message_as.js (100%) rename {e2e => e2e-tests}/cypress/tests/plugins/react_to_message_as.js (100%) rename {e2e => e2e-tests}/cypress/tests/plugins/shell.js (100%) rename {e2e => e2e-tests}/cypress/tests/plugins/url_health_check.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/bots.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/bots.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/brand.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/brand.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/channel.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/channel.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/cloud.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/cloud.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/cloud_default_config.json (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/cluster.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/cluster.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/common.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/common.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/data_retention.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/data_retention.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/helpers.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/index.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/keycloak.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/keycloak.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/keycloak_realm.json (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/ldap.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/ldap.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/on_prem_default_config.json (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/playbooks.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/plugin.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/plugin.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/preference.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/preference.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/role.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/role.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/saml.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/saml.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/scheme.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/scheme.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/setup.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/status.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/status.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/system.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/system.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/team.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/team.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/user.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/user.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/webhooks.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/api/webhooks.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/api_commands.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/assertions.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/client-impl.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/client.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/client.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/common_login_commands.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/common_login_commands.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/constants.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/db_commands.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/email.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/env.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/extended_commands.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/extended_commands.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/external_commands.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/external_commands.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/fetch_commands.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/index.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/index.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/keycloak_commands.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/keycloak_commands.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ldap_commands.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ldap_commands.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ldap_server_commands.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ldap_server_commands.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/notification.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/okta_commands.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/saml_commands.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/shell.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/shell.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/task_commands.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/account_settings_modal.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/account_settings_modal.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/announcement_bar.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/announcement_bar.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/boards.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/boards.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/channel.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/channel.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/channel_header.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/channel_header.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/channel_sidebar.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/cloud_billing.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/cloud_billing.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/common.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/common.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/compliance_export.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/compliance_export.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/data_retention.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/data_retention.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/emoji.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/extend_testing_library.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/extend_testing_library.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/file_preview.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/file_preview.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/global_header.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/global_header.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/index.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/login.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/login.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/menu.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/menu.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/mfa.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/mfa.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/modal.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/modal.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/playbooks.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/post.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/post_dropdown_menu.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/post_dropdown_menu.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/search.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/sidebar_left.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/sidebar_right.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/sidebar_right.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/suggestion_list.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/suggestion_list.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/system.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/system.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/team.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/tooltip.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui/tooltip.js (100%) rename {e2e => e2e-tests}/cypress/tests/support/ui_commands.ts (100%) rename {e2e => e2e-tests}/cypress/tests/support/win.d.ts (100%) rename {e2e => e2e-tests}/cypress/tests/types/index.ts (100%) rename {e2e => e2e-tests}/cypress/tests/utils/admin_console.js (100%) rename {e2e => e2e-tests}/cypress/tests/utils/benchmark.js (100%) rename {e2e => e2e-tests}/cypress/tests/utils/config.js (100%) rename {e2e => e2e-tests}/cypress/tests/utils/constants.js (100%) rename {e2e => e2e-tests}/cypress/tests/utils/email.js (100%) rename {e2e => e2e-tests}/cypress/tests/utils/file.js (100%) rename {e2e => e2e-tests}/cypress/tests/utils/index.js (100%) rename {e2e => e2e-tests}/cypress/tests/utils/plugins.js (100%) rename {e2e => e2e-tests}/cypress/tests/utils/timezone.js (100%) rename {e2e => e2e-tests}/cypress/tsconfig.json (100%) rename {e2e => e2e-tests}/cypress/utils/artifacts.js (100%) rename {e2e => e2e-tests}/cypress/utils/constants.js (100%) rename {e2e => e2e-tests}/cypress/utils/dashboard.js (100%) rename {e2e => e2e-tests}/cypress/utils/even_distribution.js (100%) rename {e2e => e2e-tests}/cypress/utils/even_distribution.test.js (100%) rename {e2e => e2e-tests}/cypress/utils/file.js (100%) rename {e2e => e2e-tests}/cypress/utils/report.js (100%) rename {e2e => e2e-tests}/cypress/utils/test_cases.js (100%) rename {e2e => e2e-tests}/cypress/utils/webhook_utils.js (100%) rename {e2e => e2e-tests}/cypress/webhook_serve.js (100%) rename {e2e => e2e-tests}/playwright/.eslintignore (100%) rename {e2e => e2e-tests}/playwright/.eslintrc.json (100%) rename {e2e => e2e-tests}/playwright/.percy.yml (100%) rename {e2e => e2e-tests}/playwright/.prettierignore (100%) rename {e2e => e2e-tests}/playwright/.prettierrc.json (100%) rename {e2e => e2e-tests}/playwright/README.md (100%) rename {e2e => e2e-tests}/playwright/global_setup.ts (100%) rename {e2e => e2e-tests}/playwright/package-lock.json (100%) rename {e2e => e2e-tests}/playwright/package.json (100%) rename {e2e => e2e-tests}/playwright/playwright.config.ts (100%) rename {e2e => e2e-tests}/playwright/sample.env (100%) rename {e2e => e2e-tests}/playwright/support/asset/mattermost-icon_128x128.png (100%) rename {e2e => e2e-tests}/playwright/support/browser_context.ts (100%) rename {e2e => e2e-tests}/playwright/support/constant.ts (100%) rename {e2e => e2e-tests}/playwright/support/flag.ts (100%) rename {e2e => e2e-tests}/playwright/support/server/channel.ts (100%) rename {e2e => e2e-tests}/playwright/support/server/client.ts (100%) rename {e2e => e2e-tests}/playwright/support/server/default_config.ts (100%) rename {e2e => e2e-tests}/playwright/support/server/index.ts (100%) rename {e2e => e2e-tests}/playwright/support/server/init.ts (100%) rename {e2e => e2e-tests}/playwright/support/server/team.ts (100%) rename {e2e => e2e-tests}/playwright/support/server/user.ts (100%) rename {e2e => e2e-tests}/playwright/support/test_action.ts (100%) rename {e2e => e2e-tests}/playwright/support/test_fixture.ts (100%) rename {e2e => e2e-tests}/playwright/support/ui/components/boards/create_modal.ts (100%) rename {e2e => e2e-tests}/playwright/support/ui/components/boards/sidebar.ts (100%) rename {e2e => e2e-tests}/playwright/support/ui/components/channels/app_bar.ts (100%) rename {e2e => e2e-tests}/playwright/support/ui/components/channels/header.ts (100%) rename {e2e => e2e-tests}/playwright/support/ui/components/channels/post.ts (100%) rename {e2e => e2e-tests}/playwright/support/ui/components/channels/post_create.ts (100%) rename {e2e => e2e-tests}/playwright/support/ui/components/channels/sidebar_right.ts (100%) rename {e2e => e2e-tests}/playwright/support/ui/components/global_header.ts (100%) rename {e2e => e2e-tests}/playwright/support/ui/components/index.ts (100%) rename {e2e => e2e-tests}/playwright/support/ui/pages/boards_create.ts (100%) rename {e2e => e2e-tests}/playwright/support/ui/pages/boards_view.ts (100%) rename {e2e => e2e-tests}/playwright/support/ui/pages/channels.ts (100%) rename {e2e => e2e-tests}/playwright/support/ui/pages/index.ts (100%) rename {e2e => e2e-tests}/playwright/support/ui/pages/landing_login.ts (100%) rename {e2e => e2e-tests}/playwright/support/ui/pages/login.ts (100%) rename {e2e => e2e-tests}/playwright/support/ui/pages/signup.ts (100%) rename {e2e => e2e-tests}/playwright/support/util.ts (100%) rename {e2e => e2e-tests}/playwright/support/visual/index.ts (100%) rename {e2e => e2e-tests}/playwright/support/visual/percy.ts (100%) rename {e2e => e2e-tests}/playwright/test.config.ts (100%) rename {e2e => e2e-tests}/playwright/tests/functional/boards/board-creation-and-set-up/create_empty_board.spec.ts (100%) rename {e2e => e2e-tests}/playwright/tests/visual/boards/board_template.spec.ts (100%) rename {e2e => e2e-tests}/playwright/tests/visual/boards/board_template.spec.ts-snapshots/board-template-chrome-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/boards/board_template.spec.ts-snapshots/board-template-firefox-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/boards/board_template.spec.ts-snapshots/board-template-ipad-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/boards/view_untitled_board.spec.ts (100%) rename {e2e => e2e-tests}/playwright/tests/visual/boards/view_untitled_board.spec.ts-snapshots/view-untitled-board-chrome-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/boards/view_untitled_board.spec.ts-snapshots/view-untitled-board-firefox-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/boards/view_untitled_board.spec.ts-snapshots/view-untitled-board-ipad-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/channels/intro_channel.spec.ts (100%) rename {e2e => e2e-tests}/playwright/tests/visual/channels/intro_channel.spec.ts-snapshots/intro-to-channel-as-regular-user-chrome-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/channels/intro_channel.spec.ts-snapshots/intro-to-channel-as-regular-user-firefox-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/channels/intro_channel.spec.ts-snapshots/intro-to-channel-as-regular-user-ipad-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/channels/intro_channel.spec.ts-snapshots/intro-to-channel-as-regular-user-iphone-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/common/landing_page.spec.ts (100%) rename {e2e => e2e-tests}/playwright/tests/visual/common/landing_page.spec.ts-snapshots/landing-login-chrome-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/common/landing_page.spec.ts-snapshots/landing-login-firefox-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/common/landing_page.spec.ts-snapshots/landing-login-ipad-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/common/landing_page.spec.ts-snapshots/landing-login-iphone-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/common/login.spec.ts (100%) rename {e2e => e2e-tests}/playwright/tests/visual/common/login.spec.ts-snapshots/login-chrome-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/common/login.spec.ts-snapshots/login-error-chrome-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/common/login.spec.ts-snapshots/login-error-firefox-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/common/login.spec.ts-snapshots/login-error-ipad-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/common/login.spec.ts-snapshots/login-error-iphone-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/common/login.spec.ts-snapshots/login-firefox-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/common/login.spec.ts-snapshots/login-ipad-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/common/login.spec.ts-snapshots/login-iphone-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/common/signup_email.spec.ts (100%) rename {e2e => e2e-tests}/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-chrome-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-error-chrome-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-error-firefox-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-error-ipad-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-error-iphone-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-firefox-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-ipad-linux.png (100%) rename {e2e => e2e-tests}/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-iphone-linux.png (100%) rename {e2e => e2e-tests}/playwright/tsconfig.json (100%) diff --git a/.github/codeql/codeql-config.yml b/.github/codeql/codeql-config.yml index b4f3aa4145..6b85f522b7 100644 --- a/.github/codeql/codeql-config.yml +++ b/.github/codeql/codeql-config.yml @@ -14,6 +14,6 @@ paths-ignore: - templates - tests - 'api4/*_local.go' - - webapp/channels/e2e - webapp/channels/tests - - '**/*.test.*' \ No newline at end of file + - '**/*.test.*' + - e2e-tests diff --git a/.github/workflows/channels-ci.yml b/.github/workflows/channels-ci.yml index 5fee62d830..b861650714 100644 --- a/.github/workflows/channels-ci.yml +++ b/.github/workflows/channels-ci.yml @@ -32,14 +32,14 @@ jobs: # with: # path: | # '**/node_modules' - # 'e2e/playwright/node_modules' - # 'e2e/cypress/node_modules' - # key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('e2e/cypress/package-lock.json') }}-${{ hashFiles('e2e/playwright/package-lock.json') }} + # 'e2e-tests/playwright/node_modules' + # 'e2e-tests/cypress/node_modules' + # key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('e2e-tests/cypress/package-lock.json') }}-${{ hashFiles('e2e-tests/playwright/package-lock.json') }} - name: ci/get-node-modules # if: steps.npm-cache.outputs.cache-hit != 'true' run: | make node_modules - # make channels/e2e/playwright/node_modules + # make channels/e2e-tests/playwright/node_modules - name: ci/lint run: | npm run check @@ -63,14 +63,14 @@ jobs: # with: # path: | # '**/node_modules' - # 'e2e/playwright/node_modules' - # 'e2e/cypress/node_modules' - # key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('e2e/cypress/package-lock.json') }}-${{ hashFiles('e2e/playwright/package-lock.json') }} + # 'e2e-tests/playwright/node_modules' + # 'e2e-tests/cypress/node_modules' + # key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('e2e-tests/cypress/package-lock.json') }}-${{ hashFiles('e2e-tests/playwright/package-lock.json') }} - name: ci/get-node-modules # if: steps.npm-cache.outputs.cache-hit != 'true' run: | make node_modules - # make channels/e2e/playwright/node_modules + # make channels/e2e-tests/playwright/node_modules - name: ci/lint working-directory: webapp/channels run: | @@ -103,14 +103,14 @@ jobs: # with: # path: | # '**/node_modules' - # 'e2e/playwright/node_modules' - # 'e2e/cypress/node_modules' - # key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('e2e/cypress/package-lock.json') }}-${{ hashFiles('e2e/playwright/package-lock.json') }} + # 'e2e-tests/playwright/node_modules' + # 'e2e-tests/cypress/node_modules' + # key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('e2e-tests/cypress/package-lock.json') }}-${{ hashFiles('e2e-tests/playwright/package-lock.json') }} - name: ci/get-node-modules # if: steps.npm-cache.outputs.cache-hit != 'true' run: | make node_modules - # make channels/e2e/playwright/node_modules + # make channels/e2e-tests/playwright/node_modules - name: ci/lint run: | npm run check-types @@ -138,14 +138,14 @@ jobs: # with: # path: | # '**/node_modules' - # 'e2e/playwright/node_modules' - # 'e2e/cypress/node_modules' - # key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('e2e/cypress/package-lock.json') }}-${{ hashFiles('e2e/playwright/package-lock.json') }} + # 'e2e-tests/playwright/node_modules' + # 'e2e-tests/cypress/node_modules' + # key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('e2e-tests/cypress/package-lock.json') }}-${{ hashFiles('e2e-tests/playwright/package-lock.json') }} - name: ci/get-node-modules # if: steps.npm-cache.outputs.cache-hit != 'true' run: | make node_modules - # make channels/e2e/playwright/node_modules + # make channels/e2e-tests/playwright/node_modules - name: ci/test env: NODE_OPTIONS: --max_old_space_size=5120 @@ -174,14 +174,14 @@ jobs: # with: # path: | # '**/node_modules' - # 'e2e/playwright/node_modules' - # 'e2e/cypress/node_modules' - # key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('e2e/cypress/package-lock.json') }}-${{ hashFiles('e2e/playwright/package-lock.json') }} + # 'e2e-tests/playwright/node_modules' + # 'e2e-tests/cypress/node_modules' + # key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('e2e-tests/cypress/package-lock.json') }}-${{ hashFiles('e2e-tests/playwright/package-lock.json') }} - name: ci/get-node-modules # if: steps.npm-cache.outputs.cache-hit != 'true' run: | make node_modules - # make channels/e2e/playwright/node_modules + # make channels/e2e-tests/playwright/node_modules - name: ci/build run: | npm run build diff --git a/.github/workflows/e2e-ci.yml b/.github/workflows/e2e-tests-ci.yml similarity index 84% rename from .github/workflows/e2e-ci.yml rename to .github/workflows/e2e-tests-ci.yml index 923bb6cea4..075fea0262 100644 --- a/.github/workflows/e2e-ci.yml +++ b/.github/workflows/e2e-tests-ci.yml @@ -1,4 +1,4 @@ -name: mattermost-e2e +name: mattermost-e2e-tests on: pull_request: push: @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-22.04 defaults: run: - working-directory: e2e/cypress + working-directory: e2e-tests/cypress steps: - name: ci/checkout-repo uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 @@ -26,7 +26,7 @@ jobs: with: node-version-file: ".nvmrc" cache: npm - cache-dependency-path: 'e2e/cypress/package-lock.json' + cache-dependency-path: 'e2e-tests/cypress/package-lock.json' - name: ci/cypress/npm-install run: | npm ci @@ -37,7 +37,7 @@ jobs: runs-on: ubuntu-22.04 defaults: run: - working-directory: e2e/playwright + working-directory: e2e-tests/playwright steps: - name: ci/checkout-repo uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 @@ -47,7 +47,7 @@ jobs: with: node-version-file: ".nvmrc" cache: npm - cache-dependency-path: 'e2e/playwright/package-lock.json' + cache-dependency-path: 'e2e-tests/playwright/package-lock.json' - name: ci/get-webapp-node-modules working-directory: webapp # requires build of client and types diff --git a/.gitignore b/.gitignore index ee81c1303e..cf5b44c15e 100644 --- a/.gitignore +++ b/.gitignore @@ -23,25 +23,25 @@ config/logging.json /plugins # disable folders generated by Cypress -e2e/cypress/node_modules -e2e/cypress/tests/downloads -e2e/cypress/tests/screenshots -e2e/cypress/tests/videos -e2e/cypress/tests/integration/benchmark/__benchmarks__ -e2e/cypress/tests/integration/performance/logs -e2e/cypress/tests/fixtures/ldap_tmp -e2e/cypress/tests/fixtures/mmctl -e2e/cypress/results -e2e/cypress/.eslintcache +e2e-tests/cypress/node_modules +e2e-tests/cypress/tests/downloads +e2e-tests/cypress/tests/screenshots +e2e-tests/cypress/tests/videos +e2e-tests/cypress/tests/integration/benchmark/__benchmarks__ +e2e-tests/cypress/tests/integration/performance/logs +e2e-tests/cypress/tests/fixtures/ldap_tmp +e2e-tests/cypress/tests/fixtures/mmctl +e2e-tests/cypress/results +e2e-tests/cypress/.eslintcache # disable files/folders generated by Playwright -e2e/playwright/node_modules -e2e/playwright/playwright-report -e2e/playwright/storage_state -e2e/playwright/test-results -e2e/playwright/tests/**/*-darwin.png -e2e/playwright/tests/**/*-window.png -e2e/playwright/.eslintcache +e2e-tests/playwright/node_modules +e2e-tests/playwright/playwright-report +e2e-tests/playwright/storage_state +e2e-tests/playwright/test-results +e2e-tests/playwright/tests/**/*-darwin.png +e2e-tests/playwright/tests/**/*-window.png +e2e-tests/playwright/.eslintcache # Enterprise & products imports files imports/imports.go diff --git a/e2e/.gitignore b/e2e-tests/.gitignore similarity index 100% rename from e2e/.gitignore rename to e2e-tests/.gitignore diff --git a/e2e/cypress/.eslintignore b/e2e-tests/cypress/.eslintignore similarity index 100% rename from e2e/cypress/.eslintignore rename to e2e-tests/cypress/.eslintignore diff --git a/e2e/cypress/.eslintrc.json b/e2e-tests/cypress/.eslintrc.json similarity index 100% rename from e2e/cypress/.eslintrc.json rename to e2e-tests/cypress/.eslintrc.json diff --git a/e2e/cypress/Dockerfile.webhook b/e2e-tests/cypress/Dockerfile.webhook similarity index 100% rename from e2e/cypress/Dockerfile.webhook rename to e2e-tests/cypress/Dockerfile.webhook diff --git a/e2e/cypress/README-Subpath.md b/e2e-tests/cypress/README-Subpath.md similarity index 100% rename from e2e/cypress/README-Subpath.md rename to e2e-tests/cypress/README-Subpath.md diff --git a/e2e/cypress/cypress.config.ts b/e2e-tests/cypress/cypress.config.ts similarity index 100% rename from e2e/cypress/cypress.config.ts rename to e2e-tests/cypress/cypress.config.ts diff --git a/e2e/cypress/generate_test_cycle.js b/e2e-tests/cypress/generate_test_cycle.js similarity index 100% rename from e2e/cypress/generate_test_cycle.js rename to e2e-tests/cypress/generate_test_cycle.js diff --git a/e2e/cypress/package-lock.json b/e2e-tests/cypress/package-lock.json similarity index 100% rename from e2e/cypress/package-lock.json rename to e2e-tests/cypress/package-lock.json diff --git a/e2e/cypress/package.json b/e2e-tests/cypress/package.json similarity index 100% rename from e2e/cypress/package.json rename to e2e-tests/cypress/package.json diff --git a/e2e/cypress/patches/@testing-library+cypress+9.0.0.patch b/e2e-tests/cypress/patches/@testing-library+cypress+9.0.0.patch similarity index 100% rename from e2e/cypress/patches/@testing-library+cypress+9.0.0.patch rename to e2e-tests/cypress/patches/@testing-library+cypress+9.0.0.patch diff --git a/e2e/cypress/run_test_cycle.js b/e2e-tests/cypress/run_test_cycle.js similarity index 100% rename from e2e/cypress/run_test_cycle.js rename to e2e-tests/cypress/run_test_cycle.js diff --git a/e2e/cypress/run_tests.js b/e2e-tests/cypress/run_tests.js similarity index 100% rename from e2e/cypress/run_tests.js rename to e2e-tests/cypress/run_tests.js diff --git a/e2e/cypress/save_report.js b/e2e-tests/cypress/save_report.js similarity index 100% rename from e2e/cypress/save_report.js rename to e2e-tests/cypress/save_report.js diff --git a/e2e/cypress/tests/extensions/Ignore-X-Frame-headers/background.js b/e2e-tests/cypress/tests/extensions/Ignore-X-Frame-headers/background.js similarity index 100% rename from e2e/cypress/tests/extensions/Ignore-X-Frame-headers/background.js rename to e2e-tests/cypress/tests/extensions/Ignore-X-Frame-headers/background.js diff --git a/e2e/cypress/tests/extensions/Ignore-X-Frame-headers/manifest.json b/e2e-tests/cypress/tests/extensions/Ignore-X-Frame-headers/manifest.json similarity index 100% rename from e2e/cypress/tests/extensions/Ignore-X-Frame-headers/manifest.json rename to e2e-tests/cypress/tests/extensions/Ignore-X-Frame-headers/manifest.json diff --git a/e2e/cypress/tests/fixtures/MM-logo-horizontal.png b/e2e-tests/cypress/tests/fixtures/MM-logo-horizontal.png similarity index 100% rename from e2e/cypress/tests/fixtures/MM-logo-horizontal.png rename to e2e-tests/cypress/tests/fixtures/MM-logo-horizontal.png diff --git a/e2e/cypress/tests/fixtures/animated-gif-image-file.gif b/e2e-tests/cypress/tests/fixtures/animated-gif-image-file.gif similarity index 100% rename from e2e/cypress/tests/fixtures/animated-gif-image-file.gif rename to e2e-tests/cypress/tests/fixtures/animated-gif-image-file.gif diff --git a/e2e/cypress/tests/fixtures/bmp-image-file.bmp b/e2e-tests/cypress/tests/fixtures/bmp-image-file.bmp similarity index 100% rename from e2e/cypress/tests/fixtures/bmp-image-file.bmp rename to e2e-tests/cypress/tests/fixtures/bmp-image-file.bmp diff --git a/e2e/cypress/tests/fixtures/bot-default-avatar.png b/e2e-tests/cypress/tests/fixtures/bot-default-avatar.png similarity index 100% rename from e2e/cypress/tests/fixtures/bot-default-avatar.png rename to e2e-tests/cypress/tests/fixtures/bot-default-avatar.png diff --git a/e2e/cypress/tests/fixtures/client_billing.json b/e2e-tests/cypress/tests/fixtures/client_billing.json similarity index 100% rename from e2e/cypress/tests/fixtures/client_billing.json rename to e2e-tests/cypress/tests/fixtures/client_billing.json diff --git a/e2e/cypress/tests/fixtures/console-example-inputs.json b/e2e-tests/cypress/tests/fixtures/console-example-inputs.json similarity index 100% rename from e2e/cypress/tests/fixtures/console-example-inputs.json rename to e2e-tests/cypress/tests/fixtures/console-example-inputs.json diff --git a/e2e/cypress/tests/fixtures/date_time_format.js b/e2e-tests/cypress/tests/fixtures/date_time_format.js similarity index 100% rename from e2e/cypress/tests/fixtures/date_time_format.js rename to e2e-tests/cypress/tests/fixtures/date_time_format.js diff --git a/e2e/cypress/tests/fixtures/favicon-16x16.png b/e2e-tests/cypress/tests/fixtures/favicon-16x16.png similarity index 100% rename from e2e/cypress/tests/fixtures/favicon-16x16.png rename to e2e-tests/cypress/tests/fixtures/favicon-16x16.png diff --git a/e2e/cypress/tests/fixtures/favicon-default-16x16.png b/e2e-tests/cypress/tests/fixtures/favicon-default-16x16.png similarity index 100% rename from e2e/cypress/tests/fixtures/favicon-default-16x16.png rename to e2e-tests/cypress/tests/fixtures/favicon-default-16x16.png diff --git a/e2e/cypress/tests/fixtures/favicon-mentions-16x16.png b/e2e-tests/cypress/tests/fixtures/favicon-mentions-16x16.png similarity index 100% rename from e2e/cypress/tests/fixtures/favicon-mentions-16x16.png rename to e2e-tests/cypress/tests/fixtures/favicon-mentions-16x16.png diff --git a/e2e/cypress/tests/fixtures/favicon-unread-16x16.png b/e2e-tests/cypress/tests/fixtures/favicon-unread-16x16.png similarity index 100% rename from e2e/cypress/tests/fixtures/favicon-unread-16x16.png rename to e2e-tests/cypress/tests/fixtures/favicon-unread-16x16.png diff --git a/e2e/cypress/tests/fixtures/gif-image-file-resized.gif b/e2e-tests/cypress/tests/fixtures/gif-image-file-resized.gif similarity index 100% rename from e2e/cypress/tests/fixtures/gif-image-file-resized.gif rename to e2e-tests/cypress/tests/fixtures/gif-image-file-resized.gif diff --git a/e2e/cypress/tests/fixtures/gif-image-file.gif b/e2e-tests/cypress/tests/fixtures/gif-image-file.gif similarity index 100% rename from e2e/cypress/tests/fixtures/gif-image-file.gif rename to e2e-tests/cypress/tests/fixtures/gif-image-file.gif diff --git a/e2e/cypress/tests/fixtures/hooks/message_menus.json b/e2e-tests/cypress/tests/fixtures/hooks/message_menus.json similarity index 100% rename from e2e/cypress/tests/fixtures/hooks/message_menus.json rename to e2e-tests/cypress/tests/fixtures/hooks/message_menus.json diff --git a/e2e/cypress/tests/fixtures/hooks/message_menus_with_datasource.json b/e2e-tests/cypress/tests/fixtures/hooks/message_menus_with_datasource.json similarity index 100% rename from e2e/cypress/tests/fixtures/hooks/message_menus_with_datasource.json rename to e2e-tests/cypress/tests/fixtures/hooks/message_menus_with_datasource.json diff --git a/e2e/cypress/tests/fixtures/huge-image.jpg b/e2e-tests/cypress/tests/fixtures/huge-image.jpg similarity index 100% rename from e2e/cypress/tests/fixtures/huge-image.jpg rename to e2e-tests/cypress/tests/fixtures/huge-image.jpg diff --git a/e2e/cypress/tests/fixtures/image-1000x40.jpg b/e2e-tests/cypress/tests/fixtures/image-1000x40.jpg similarity index 100% rename from e2e/cypress/tests/fixtures/image-1000x40.jpg rename to e2e-tests/cypress/tests/fixtures/image-1000x40.jpg diff --git a/e2e/cypress/tests/fixtures/image-1600x40.jpg b/e2e-tests/cypress/tests/fixtures/image-1600x40.jpg similarity index 100% rename from e2e/cypress/tests/fixtures/image-1600x40.jpg rename to e2e-tests/cypress/tests/fixtures/image-1600x40.jpg diff --git a/e2e/cypress/tests/fixtures/image-20x20.jpg b/e2e-tests/cypress/tests/fixtures/image-20x20.jpg similarity index 100% rename from e2e/cypress/tests/fixtures/image-20x20.jpg rename to e2e-tests/cypress/tests/fixtures/image-20x20.jpg diff --git a/e2e/cypress/tests/fixtures/image-400x40.jpg b/e2e-tests/cypress/tests/fixtures/image-400x40.jpg similarity index 100% rename from e2e/cypress/tests/fixtures/image-400x40.jpg rename to e2e-tests/cypress/tests/fixtures/image-400x40.jpg diff --git a/e2e/cypress/tests/fixtures/image-400x400.jpg b/e2e-tests/cypress/tests/fixtures/image-400x400.jpg similarity index 100% rename from e2e/cypress/tests/fixtures/image-400x400.jpg rename to e2e-tests/cypress/tests/fixtures/image-400x400.jpg diff --git a/e2e/cypress/tests/fixtures/image-40x400.jpg b/e2e-tests/cypress/tests/fixtures/image-40x400.jpg similarity index 100% rename from e2e/cypress/tests/fixtures/image-40x400.jpg rename to e2e-tests/cypress/tests/fixtures/image-40x400.jpg diff --git a/e2e/cypress/tests/fixtures/image-50x50.jpg b/e2e-tests/cypress/tests/fixtures/image-50x50.jpg similarity index 100% rename from e2e/cypress/tests/fixtures/image-50x50.jpg rename to e2e-tests/cypress/tests/fixtures/image-50x50.jpg diff --git a/e2e/cypress/tests/fixtures/image-60x60.jpg b/e2e-tests/cypress/tests/fixtures/image-60x60.jpg similarity index 100% rename from e2e/cypress/tests/fixtures/image-60x60.jpg rename to e2e-tests/cypress/tests/fixtures/image-60x60.jpg diff --git a/e2e/cypress/tests/fixtures/image-small-height.png b/e2e-tests/cypress/tests/fixtures/image-small-height.png similarity index 100% rename from e2e/cypress/tests/fixtures/image-small-height.png rename to e2e-tests/cypress/tests/fixtures/image-small-height.png diff --git a/e2e/cypress/tests/fixtures/image-small-width.png b/e2e-tests/cypress/tests/fixtures/image-small-width.png similarity index 100% rename from e2e/cypress/tests/fixtures/image-small-width.png rename to e2e-tests/cypress/tests/fixtures/image-small-width.png diff --git a/e2e/cypress/tests/fixtures/interactive_message_menus_options.json b/e2e-tests/cypress/tests/fixtures/interactive_message_menus_options.json similarity index 100% rename from e2e/cypress/tests/fixtures/interactive_message_menus_options.json rename to e2e-tests/cypress/tests/fixtures/interactive_message_menus_options.json diff --git a/e2e/cypress/tests/fixtures/jpg-image-file.jpg b/e2e-tests/cypress/tests/fixtures/jpg-image-file.jpg similarity index 100% rename from e2e/cypress/tests/fixtures/jpg-image-file.jpg rename to e2e-tests/cypress/tests/fixtures/jpg-image-file.jpg diff --git a/e2e/cypress/tests/fixtures/ldap-add-user.ldif b/e2e-tests/cypress/tests/fixtures/ldap-add-user.ldif similarity index 100% rename from e2e/cypress/tests/fixtures/ldap-add-user.ldif rename to e2e-tests/cypress/tests/fixtures/ldap-add-user.ldif diff --git a/e2e/cypress/tests/fixtures/ldap-reset-data.ldif b/e2e-tests/cypress/tests/fixtures/ldap-reset-data.ldif similarity index 100% rename from e2e/cypress/tests/fixtures/ldap-reset-data.ldif rename to e2e-tests/cypress/tests/fixtures/ldap-reset-data.ldif diff --git a/e2e/cypress/tests/fixtures/ldap_users.json b/e2e-tests/cypress/tests/fixtures/ldap_users.json similarity index 100% rename from e2e/cypress/tests/fixtures/ldap_users.json rename to e2e-tests/cypress/tests/fixtures/ldap_users.json diff --git a/e2e/cypress/tests/fixtures/long_text_post.txt b/e2e-tests/cypress/tests/fixtures/long_text_post.txt similarity index 100% rename from e2e/cypress/tests/fixtures/long_text_post.txt rename to e2e-tests/cypress/tests/fixtures/long_text_post.txt diff --git a/e2e/cypress/tests/fixtures/m4a-audio-file.m4a b/e2e-tests/cypress/tests/fixtures/m4a-audio-file.m4a similarity index 100% rename from e2e/cypress/tests/fixtures/m4a-audio-file.m4a rename to e2e-tests/cypress/tests/fixtures/m4a-audio-file.m4a diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_basic.html b/e2e-tests/cypress/tests/fixtures/markdown/markdown_basic.html similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_basic.html rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_basic.html diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_basic.md b/e2e-tests/cypress/tests/fixtures/markdown/markdown_basic.md similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_basic.md rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_basic.md diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_block_quotes_1.html b/e2e-tests/cypress/tests/fixtures/markdown/markdown_block_quotes_1.html similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_block_quotes_1.html rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_block_quotes_1.html diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_block_quotes_1.md b/e2e-tests/cypress/tests/fixtures/markdown/markdown_block_quotes_1.md similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_block_quotes_1.md rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_block_quotes_1.md diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_block_quotes_2.md b/e2e-tests/cypress/tests/fixtures/markdown/markdown_block_quotes_2.md similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_block_quotes_2.md rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_block_quotes_2.md diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_carriage_return.html b/e2e-tests/cypress/tests/fixtures/markdown/markdown_carriage_return.html similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_carriage_return.html rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_carriage_return.html diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_carriage_return.md b/e2e-tests/cypress/tests/fixtures/markdown/markdown_carriage_return.md similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_carriage_return.md rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_carriage_return.md diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_carriage_return_two_lines.html b/e2e-tests/cypress/tests/fixtures/markdown/markdown_carriage_return_two_lines.html similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_carriage_return_two_lines.html rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_carriage_return_two_lines.html diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_carriage_return_two_lines.md b/e2e-tests/cypress/tests/fixtures/markdown/markdown_carriage_return_two_lines.md similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_carriage_return_two_lines.md rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_carriage_return_two_lines.md diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_code_block.html b/e2e-tests/cypress/tests/fixtures/markdown/markdown_code_block.html similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_code_block.html rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_code_block.html diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_code_block.md b/e2e-tests/cypress/tests/fixtures/markdown/markdown_code_block.md similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_code_block.md rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_code_block.md diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_code_syntax.html b/e2e-tests/cypress/tests/fixtures/markdown/markdown_code_syntax.html similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_code_syntax.html rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_code_syntax.html diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_escape_characters.html b/e2e-tests/cypress/tests/fixtures/markdown/markdown_escape_characters.html similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_escape_characters.html rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_escape_characters.html diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_escape_characters.md b/e2e-tests/cypress/tests/fixtures/markdown/markdown_escape_characters.md similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_escape_characters.md rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_escape_characters.md diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_headings.html b/e2e-tests/cypress/tests/fixtures/markdown/markdown_headings.html similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_headings.html rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_headings.html diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_headings.md b/e2e-tests/cypress/tests/fixtures/markdown/markdown_headings.md similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_headings.md rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_headings.md diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_inline_code.html b/e2e-tests/cypress/tests/fixtures/markdown/markdown_inline_code.html similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_inline_code.html rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_inline_code.html diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_inline_code.md b/e2e-tests/cypress/tests/fixtures/markdown/markdown_inline_code.md similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_inline_code.md rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_inline_code.md diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_inline_images_1.md b/e2e-tests/cypress/tests/fixtures/markdown/markdown_inline_images_1.md similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_inline_images_1.md rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_inline_images_1.md diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_inline_images_2.md b/e2e-tests/cypress/tests/fixtures/markdown/markdown_inline_images_2.md similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_inline_images_2.md rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_inline_images_2.md diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_inline_images_3.md b/e2e-tests/cypress/tests/fixtures/markdown/markdown_inline_images_3.md similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_inline_images_3.md rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_inline_images_3.md diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_inline_images_4.md b/e2e-tests/cypress/tests/fixtures/markdown/markdown_inline_images_4.md similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_inline_images_4.md rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_inline_images_4.md diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_inline_images_5.md b/e2e-tests/cypress/tests/fixtures/markdown/markdown_inline_images_5.md similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_inline_images_5.md rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_inline_images_5.md diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_inline_images_6.md b/e2e-tests/cypress/tests/fixtures/markdown/markdown_inline_images_6.md similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_inline_images_6.md rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_inline_images_6.md diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_latex.html b/e2e-tests/cypress/tests/fixtures/markdown/markdown_latex.html similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_latex.html rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_latex.html diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_latex.md b/e2e-tests/cypress/tests/fixtures/markdown/markdown_latex.md similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_latex.md rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_latex.md diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_lines.html b/e2e-tests/cypress/tests/fixtures/markdown/markdown_lines.html similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_lines.html rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_lines.html diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_lines.md b/e2e-tests/cypress/tests/fixtures/markdown/markdown_lines.md similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_lines.md rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_lines.md diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_list.html b/e2e-tests/cypress/tests/fixtures/markdown/markdown_list.html similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_list.html rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_list.html diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_not_autolink.html b/e2e-tests/cypress/tests/fixtures/markdown/markdown_not_autolink.html similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_not_autolink.html rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_not_autolink.html diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_not_autolink.md b/e2e-tests/cypress/tests/fixtures/markdown/markdown_not_autolink.md similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_not_autolink.md rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_not_autolink.md diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_not_in_code_block.html b/e2e-tests/cypress/tests/fixtures/markdown/markdown_not_in_code_block.html similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_not_in_code_block.html rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_not_in_code_block.html diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_not_in_code_block.md b/e2e-tests/cypress/tests/fixtures/markdown/markdown_not_in_code_block.md similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_not_in_code_block.md rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_not_in_code_block.md diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_postgres.html b/e2e-tests/cypress/tests/fixtures/markdown/markdown_postgres.html similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_postgres.html rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_postgres.html diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_postgres.md b/e2e-tests/cypress/tests/fixtures/markdown/markdown_postgres.md similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_postgres.md rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_postgres.md diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_python.html b/e2e-tests/cypress/tests/fixtures/markdown/markdown_python.html similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_python.html rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_python.html diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_python.md b/e2e-tests/cypress/tests/fixtures/markdown/markdown_python.md similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_python.md rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_python.md diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_shell.html b/e2e-tests/cypress/tests/fixtures/markdown/markdown_shell.html similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_shell.html rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_shell.html diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_shell.md b/e2e-tests/cypress/tests/fixtures/markdown/markdown_shell.md similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_shell.md rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_shell.md diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_tables.html b/e2e-tests/cypress/tests/fixtures/markdown/markdown_tables.html similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_tables.html rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_tables.html diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_test_basic.html b/e2e-tests/cypress/tests/fixtures/markdown/markdown_test_basic.html similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_test_basic.html rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_test_basic.html diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_text_style.html b/e2e-tests/cypress/tests/fixtures/markdown/markdown_text_style.html similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_text_style.html rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_text_style.html diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_text_style.md b/e2e-tests/cypress/tests/fixtures/markdown/markdown_text_style.md similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_text_style.md rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_text_style.md diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_typescript.html b/e2e-tests/cypress/tests/fixtures/markdown/markdown_typescript.html similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_typescript.html rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_typescript.html diff --git a/e2e/cypress/tests/fixtures/markdown/markdown_typescript.md b/e2e-tests/cypress/tests/fixtures/markdown/markdown_typescript.md similarity index 100% rename from e2e/cypress/tests/fixtures/markdown/markdown_typescript.md rename to e2e-tests/cypress/tests/fixtures/markdown/markdown_typescript.md diff --git a/e2e/cypress/tests/fixtures/mattermost-icon.png b/e2e-tests/cypress/tests/fixtures/mattermost-icon.png similarity index 100% rename from e2e/cypress/tests/fixtures/mattermost-icon.png rename to e2e-tests/cypress/tests/fixtures/mattermost-icon.png diff --git a/e2e/cypress/tests/fixtures/mattermost-icon_128x128.png b/e2e-tests/cypress/tests/fixtures/mattermost-icon_128x128.png similarity index 100% rename from e2e/cypress/tests/fixtures/mattermost-icon_128x128.png rename to e2e-tests/cypress/tests/fixtures/mattermost-icon_128x128.png diff --git a/e2e/cypress/tests/fixtures/messages.js b/e2e-tests/cypress/tests/fixtures/messages.js similarity index 100% rename from e2e/cypress/tests/fixtures/messages.js rename to e2e-tests/cypress/tests/fixtures/messages.js diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Audio/AAC.aac b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Audio/AAC.aac similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Audio/AAC.aac rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Audio/AAC.aac diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Audio/FLAC.flac b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Audio/FLAC.flac similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Audio/FLAC.flac rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Audio/FLAC.flac diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Audio/M4A.m4a b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Audio/M4A.m4a similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Audio/M4A.m4a rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Audio/M4A.m4a diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Audio/M4R.m4r b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Audio/M4R.m4r similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Audio/M4R.m4r rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Audio/M4R.m4r diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Audio/MP3.mp3 b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Audio/MP3.mp3 similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Audio/MP3.mp3 rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Audio/MP3.mp3 diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Audio/OGG.ogg b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Audio/OGG.ogg similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Audio/OGG.ogg rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Audio/OGG.ogg diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Audio/WAV.wav b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Audio/WAV.wav similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Audio/WAV.wav rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Audio/WAV.wav diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Audio/WMA.wma b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Audio/WMA.wma similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Audio/WMA.wma rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Audio/WMA.wma diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Code/JSON b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Code/JSON similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Code/JSON rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Code/JSON diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Code/Patch.diff b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Code/Patch.diff similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Code/Patch.diff rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Code/Patch.diff diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Code/Python b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Code/Python similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Code/Python rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Code/Python diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Documents/Excel.xlsx b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Documents/Excel.xlsx similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Documents/Excel.xlsx rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Documents/Excel.xlsx diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Documents/PDF.pdf b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Documents/PDF.pdf similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Documents/PDF.pdf rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Documents/PDF.pdf diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Documents/PPT.pptx b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Documents/PPT.pptx similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Documents/PPT.pptx rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Documents/PPT.pptx diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Documents/Text.txt b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Documents/Text.txt similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Documents/Text.txt rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Documents/Text.txt diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Documents/Word.docx b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Documents/Word.docx similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Documents/Word.docx rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Documents/Word.docx diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Images/BMP.bmp b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Images/BMP.bmp similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Images/BMP.bmp rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Images/BMP.bmp diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Images/GIF.gif b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Images/GIF.gif similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Images/GIF.gif rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Images/GIF.gif diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Images/JPG.jpg b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Images/JPG.jpg similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Images/JPG.jpg rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Images/JPG.jpg diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Images/PNG.png b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Images/PNG.png similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Images/PNG.png rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Images/PNG.png diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Images/PSD.psd b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Images/PSD.psd similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Images/PSD.psd rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Images/PSD.psd diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Images/TIFF.tif b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Images/TIFF.tif similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Images/TIFF.tif rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Images/TIFF.tif diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Video/AVI.avi b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Video/AVI.avi similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Video/AVI.avi rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Video/AVI.avi diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Video/MKV.mkv b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Video/MKV.mkv similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Video/MKV.mkv rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Video/MKV.mkv diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Video/MOV.mov b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Video/MOV.mov similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Video/MOV.mov rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Video/MOV.mov diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Video/MP4.mp4 b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Video/MP4.mp4 similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Video/MP4.mp4 rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Video/MP4.mp4 diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Video/MPG.mpg b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Video/MPG.mpg similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Video/MPG.mpg rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Video/MPG.mpg diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Video/WEBM.webm b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Video/WEBM.webm similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Video/WEBM.webm rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Video/WEBM.webm diff --git a/e2e/cypress/tests/fixtures/mm_file_testing/Video/WMV.wmv b/e2e-tests/cypress/tests/fixtures/mm_file_testing/Video/WMV.wmv similarity index 100% rename from e2e/cypress/tests/fixtures/mm_file_testing/Video/WMV.wmv rename to e2e-tests/cypress/tests/fixtures/mm_file_testing/Video/WMV.wmv diff --git a/e2e/cypress/tests/fixtures/mp3-audio-file.mp3 b/e2e-tests/cypress/tests/fixtures/mp3-audio-file.mp3 similarity index 100% rename from e2e/cypress/tests/fixtures/mp3-audio-file.mp3 rename to e2e-tests/cypress/tests/fixtures/mp3-audio-file.mp3 diff --git a/e2e/cypress/tests/fixtures/mp4-video-file.mp4 b/e2e-tests/cypress/tests/fixtures/mp4-video-file.mp4 similarity index 100% rename from e2e/cypress/tests/fixtures/mp4-video-file.mp4 rename to e2e-tests/cypress/tests/fixtures/mp4-video-file.mp4 diff --git a/e2e/cypress/tests/fixtures/mpeg-video-file.mpg b/e2e-tests/cypress/tests/fixtures/mpeg-video-file.mpg similarity index 100% rename from e2e/cypress/tests/fixtures/mpeg-video-file.mpg rename to e2e-tests/cypress/tests/fixtures/mpeg-video-file.mpg diff --git a/e2e/cypress/tests/fixtures/playbook-export.json b/e2e-tests/cypress/tests/fixtures/playbook-export.json similarity index 100% rename from e2e/cypress/tests/fixtures/playbook-export.json rename to e2e-tests/cypress/tests/fixtures/playbook-export.json diff --git a/e2e/cypress/tests/fixtures/png-image-file.png b/e2e-tests/cypress/tests/fixtures/png-image-file.png similarity index 100% rename from e2e/cypress/tests/fixtures/png-image-file.png rename to e2e-tests/cypress/tests/fixtures/png-image-file.png diff --git a/e2e/cypress/tests/fixtures/powerpoint-file.ppt b/e2e-tests/cypress/tests/fixtures/powerpoint-file.ppt similarity index 100% rename from e2e/cypress/tests/fixtures/powerpoint-file.ppt rename to e2e-tests/cypress/tests/fixtures/powerpoint-file.ppt diff --git a/e2e/cypress/tests/fixtures/powerpointx-file.pptx b/e2e-tests/cypress/tests/fixtures/powerpointx-file.pptx similarity index 100% rename from e2e/cypress/tests/fixtures/powerpointx-file.pptx rename to e2e-tests/cypress/tests/fixtures/powerpointx-file.pptx diff --git a/e2e/cypress/tests/fixtures/saml_ldap_users.json b/e2e-tests/cypress/tests/fixtures/saml_ldap_users.json similarity index 100% rename from e2e/cypress/tests/fixtures/saml_ldap_users.json rename to e2e-tests/cypress/tests/fixtures/saml_ldap_users.json diff --git a/e2e/cypress/tests/fixtures/saml_users.json b/e2e-tests/cypress/tests/fixtures/saml_users.json similarity index 100% rename from e2e/cypress/tests/fixtures/saml_users.json rename to e2e-tests/cypress/tests/fixtures/saml_users.json diff --git a/e2e/cypress/tests/fixtures/small-image.png b/e2e-tests/cypress/tests/fixtures/small-image.png similarity index 100% rename from e2e/cypress/tests/fixtures/small-image.png rename to e2e-tests/cypress/tests/fixtures/small-image.png diff --git a/e2e/cypress/tests/fixtures/svg.svg b/e2e-tests/cypress/tests/fixtures/svg.svg similarity index 100% rename from e2e/cypress/tests/fixtures/svg.svg rename to e2e-tests/cypress/tests/fixtures/svg.svg diff --git a/e2e/cypress/tests/fixtures/system-roles-console-access.json b/e2e-tests/cypress/tests/fixtures/system-roles-console-access.json similarity index 100% rename from e2e/cypress/tests/fixtures/system-roles-console-access.json rename to e2e-tests/cypress/tests/fixtures/system-roles-console-access.json diff --git a/e2e/cypress/tests/fixtures/theme.json b/e2e-tests/cypress/tests/fixtures/theme.json similarity index 100% rename from e2e/cypress/tests/fixtures/theme.json rename to e2e-tests/cypress/tests/fixtures/theme.json diff --git a/e2e/cypress/tests/fixtures/tiff-image-file.tif b/e2e-tests/cypress/tests/fixtures/tiff-image-file.tif similarity index 100% rename from e2e/cypress/tests/fixtures/tiff-image-file.tif rename to e2e-tests/cypress/tests/fixtures/tiff-image-file.tif diff --git a/e2e/cypress/tests/fixtures/timeouts.js b/e2e-tests/cypress/tests/fixtures/timeouts.js similarity index 100% rename from e2e/cypress/tests/fixtures/timeouts.js rename to e2e-tests/cypress/tests/fixtures/timeouts.js diff --git a/e2e/cypress/tests/fixtures/txt-changed-as-png.png b/e2e-tests/cypress/tests/fixtures/txt-changed-as-png.png similarity index 100% rename from e2e/cypress/tests/fixtures/txt-changed-as-png.png rename to e2e-tests/cypress/tests/fixtures/txt-changed-as-png.png diff --git a/e2e/cypress/tests/fixtures/webhook_icon.jpg b/e2e-tests/cypress/tests/fixtures/webhook_icon.jpg similarity index 100% rename from e2e/cypress/tests/fixtures/webhook_icon.jpg rename to e2e-tests/cypress/tests/fixtures/webhook_icon.jpg diff --git a/e2e/cypress/tests/fixtures/webhook_override_icon.png b/e2e-tests/cypress/tests/fixtures/webhook_override_icon.png similarity index 100% rename from e2e/cypress/tests/fixtures/webhook_override_icon.png rename to e2e-tests/cypress/tests/fixtures/webhook_override_icon.png diff --git a/e2e/cypress/tests/fixtures/word-file.doc b/e2e-tests/cypress/tests/fixtures/word-file.doc similarity index 100% rename from e2e/cypress/tests/fixtures/word-file.doc rename to e2e-tests/cypress/tests/fixtures/word-file.doc diff --git a/e2e/cypress/tests/fixtures/wordx-file.docx b/e2e-tests/cypress/tests/fixtures/wordx-file.docx similarity index 100% rename from e2e/cypress/tests/fixtures/wordx-file.docx rename to e2e-tests/cypress/tests/fixtures/wordx-file.docx diff --git a/e2e/cypress/tests/integration/boards/card_badges_spec.ts b/e2e-tests/cypress/tests/integration/boards/card_badges_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/boards/card_badges_spec.ts rename to e2e-tests/cypress/tests/integration/boards/card_badges_spec.ts diff --git a/e2e/cypress/tests/integration/boards/card_urlproperty_spec.ts b/e2e-tests/cypress/tests/integration/boards/card_urlproperty_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/boards/card_urlproperty_spec.ts rename to e2e-tests/cypress/tests/integration/boards/card_urlproperty_spec.ts diff --git a/e2e/cypress/tests/integration/boards/create_board_spec.ts b/e2e-tests/cypress/tests/integration/boards/create_board_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/boards/create_board_spec.ts rename to e2e-tests/cypress/tests/integration/boards/create_board_spec.ts diff --git a/e2e/cypress/tests/integration/boards/group_by_property_spec.ts b/e2e-tests/cypress/tests/integration/boards/group_by_property_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/boards/group_by_property_spec.ts rename to e2e-tests/cypress/tests/integration/boards/group_by_property_spec.ts diff --git a/e2e/cypress/tests/integration/boards/manage_groups_spec.ts b/e2e-tests/cypress/tests/integration/boards/manage_groups_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/boards/manage_groups_spec.ts rename to e2e-tests/cypress/tests/integration/boards/manage_groups_spec.ts diff --git a/e2e/cypress/tests/integration/channels/accessibility/accessibility_account_settings_spec.js b/e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_account_settings_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/accessibility/accessibility_account_settings_spec.js rename to e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_account_settings_spec.js diff --git a/e2e/cypress/tests/integration/channels/accessibility/accessibility_buttons_spec.js b/e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_buttons_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/accessibility/accessibility_buttons_spec.js rename to e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_buttons_spec.js diff --git a/e2e/cypress/tests/integration/channels/accessibility/accessibility_dropdowns_spec.js b/e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_dropdowns_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/accessibility/accessibility_dropdowns_spec.js rename to e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_dropdowns_spec.js diff --git a/e2e/cypress/tests/integration/channels/accessibility/accessibility_image_spec.js b/e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_image_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/accessibility/accessibility_image_spec.js rename to e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_image_spec.js diff --git a/e2e/cypress/tests/integration/channels/accessibility/accessibility_keyboard_usability_spec.js b/e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_keyboard_usability_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/accessibility/accessibility_keyboard_usability_spec.js rename to e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_keyboard_usability_spec.js diff --git a/e2e/cypress/tests/integration/channels/accessibility/accessibility_nav_diff_regions_spec.js b/e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_nav_diff_regions_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/accessibility/accessibility_nav_diff_regions_spec.js rename to e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_nav_diff_regions_spec.js diff --git a/e2e/cypress/tests/integration/channels/accessibility/accessibility_popovers_spec.js b/e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_popovers_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/accessibility/accessibility_popovers_spec.js rename to e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_popovers_spec.js diff --git a/e2e/cypress/tests/integration/channels/accessibility/accessibility_post_spec.js b/e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_post_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/accessibility/accessibility_post_spec.js rename to e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_post_spec.js diff --git a/e2e/cypress/tests/integration/channels/accessibility/accessibility_sidebar_dm_spec.js b/e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_sidebar_dm_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/accessibility/accessibility_sidebar_dm_spec.js rename to e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_sidebar_dm_spec.js diff --git a/e2e/cypress/tests/integration/channels/accessibility/accessibility_sidebar_spec.ts b/e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_sidebar_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/accessibility/accessibility_sidebar_spec.ts rename to e2e-tests/cypress/tests/integration/channels/accessibility/accessibility_sidebar_spec.ts diff --git a/e2e/cypress/tests/integration/channels/account_settings/account_settings_spec.ts b/e2e-tests/cypress/tests/integration/channels/account_settings/account_settings_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/account_settings/account_settings_spec.ts rename to e2e-tests/cypress/tests/integration/channels/account_settings/account_settings_spec.ts diff --git a/e2e/cypress/tests/integration/channels/account_settings/main_menu_stays_open_spec.ts b/e2e-tests/cypress/tests/integration/channels/account_settings/main_menu_stays_open_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/account_settings/main_menu_stays_open_spec.ts rename to e2e-tests/cypress/tests/integration/channels/account_settings/main_menu_stays_open_spec.ts diff --git a/e2e/cypress/tests/integration/channels/account_settings/profile/account_settings_position_spec.ts b/e2e-tests/cypress/tests/integration/channels/account_settings/profile/account_settings_position_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/account_settings/profile/account_settings_position_spec.ts rename to e2e-tests/cypress/tests/integration/channels/account_settings/profile/account_settings_position_spec.ts diff --git a/e2e/cypress/tests/integration/channels/account_settings/profile/email_spec.ts b/e2e-tests/cypress/tests/integration/channels/account_settings/profile/email_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/account_settings/profile/email_spec.ts rename to e2e-tests/cypress/tests/integration/channels/account_settings/profile/email_spec.ts diff --git a/e2e/cypress/tests/integration/channels/account_settings/profile/fullname_edit_spec.ts b/e2e-tests/cypress/tests/integration/channels/account_settings/profile/fullname_edit_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/account_settings/profile/fullname_edit_spec.ts rename to e2e-tests/cypress/tests/integration/channels/account_settings/profile/fullname_edit_spec.ts diff --git a/e2e/cypress/tests/integration/channels/account_settings/profile/fullname_truncate_spec.ts b/e2e-tests/cypress/tests/integration/channels/account_settings/profile/fullname_truncate_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/account_settings/profile/fullname_truncate_spec.ts rename to e2e-tests/cypress/tests/integration/channels/account_settings/profile/fullname_truncate_spec.ts diff --git a/e2e/cypress/tests/integration/channels/account_settings/profile/help_text_link_spec.ts b/e2e-tests/cypress/tests/integration/channels/account_settings/profile/help_text_link_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/account_settings/profile/help_text_link_spec.ts rename to e2e-tests/cypress/tests/integration/channels/account_settings/profile/help_text_link_spec.ts diff --git a/e2e/cypress/tests/integration/channels/account_settings/profile/nickname_spec.ts b/e2e-tests/cypress/tests/integration/channels/account_settings/profile/nickname_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/account_settings/profile/nickname_spec.ts rename to e2e-tests/cypress/tests/integration/channels/account_settings/profile/nickname_spec.ts diff --git a/e2e/cypress/tests/integration/channels/account_settings/profile/profile_picture_change_spec.ts b/e2e-tests/cypress/tests/integration/channels/account_settings/profile/profile_picture_change_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/account_settings/profile/profile_picture_change_spec.ts rename to e2e-tests/cypress/tests/integration/channels/account_settings/profile/profile_picture_change_spec.ts diff --git a/e2e/cypress/tests/integration/channels/account_settings/profile/profile_picture_spec.ts b/e2e-tests/cypress/tests/integration/channels/account_settings/profile/profile_picture_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/account_settings/profile/profile_picture_spec.ts rename to e2e-tests/cypress/tests/integration/channels/account_settings/profile/profile_picture_spec.ts diff --git a/e2e/cypress/tests/integration/channels/account_settings/profile/username_spec.ts b/e2e-tests/cypress/tests/integration/channels/account_settings/profile/username_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/account_settings/profile/username_spec.ts rename to e2e-tests/cypress/tests/integration/channels/account_settings/profile/username_spec.ts diff --git a/e2e/cypress/tests/integration/channels/account_settings/security/access_history_spec.ts b/e2e-tests/cypress/tests/integration/channels/account_settings/security/access_history_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/account_settings/security/access_history_spec.ts rename to e2e-tests/cypress/tests/integration/channels/account_settings/security/access_history_spec.ts diff --git a/e2e/cypress/tests/integration/channels/account_settings/security/active_sessions_spec.ts b/e2e-tests/cypress/tests/integration/channels/account_settings/security/active_sessions_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/account_settings/security/active_sessions_spec.ts rename to e2e-tests/cypress/tests/integration/channels/account_settings/security/active_sessions_spec.ts diff --git a/e2e/cypress/tests/integration/channels/account_settings/security/password_spec.ts b/e2e-tests/cypress/tests/integration/channels/account_settings/security/password_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/account_settings/security/password_spec.ts rename to e2e-tests/cypress/tests/integration/channels/account_settings/security/password_spec.ts diff --git a/e2e/cypress/tests/integration/channels/ad_ldap/saml_ldap_sync_id_attrib_spec.js b/e2e-tests/cypress/tests/integration/channels/ad_ldap/saml_ldap_sync_id_attrib_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/ad_ldap/saml_ldap_sync_id_attrib_spec.js rename to e2e-tests/cypress/tests/integration/channels/ad_ldap/saml_ldap_sync_id_attrib_spec.js diff --git a/e2e/cypress/tests/integration/channels/ad_ldap/saml_ldap_sync_remove_spec.js b/e2e-tests/cypress/tests/integration/channels/ad_ldap/saml_ldap_sync_remove_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/ad_ldap/saml_ldap_sync_remove_spec.js rename to e2e-tests/cypress/tests/integration/channels/ad_ldap/saml_ldap_sync_remove_spec.js diff --git a/e2e/cypress/tests/integration/channels/ad_ldap/saml_ldap_sync_spec.js b/e2e-tests/cypress/tests/integration/channels/ad_ldap/saml_ldap_sync_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/ad_ldap/saml_ldap_sync_spec.js rename to e2e-tests/cypress/tests/integration/channels/ad_ldap/saml_ldap_sync_spec.js diff --git a/e2e/cypress/tests/integration/channels/archived_channel/archive_channel_add_reaction_spec.ts b/e2e-tests/cypress/tests/integration/channels/archived_channel/archive_channel_add_reaction_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/archived_channel/archive_channel_add_reaction_spec.ts rename to e2e-tests/cypress/tests/integration/channels/archived_channel/archive_channel_add_reaction_spec.ts diff --git a/e2e/cypress/tests/integration/channels/archived_channel/archive_channel_header_spec.ts b/e2e-tests/cypress/tests/integration/channels/archived_channel/archive_channel_header_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/archived_channel/archive_channel_header_spec.ts rename to e2e-tests/cypress/tests/integration/channels/archived_channel/archive_channel_header_spec.ts diff --git a/e2e/cypress/tests/integration/channels/archived_channel/archive_channel_member_spec.ts b/e2e-tests/cypress/tests/integration/channels/archived_channel/archive_channel_member_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/archived_channel/archive_channel_member_spec.ts rename to e2e-tests/cypress/tests/integration/channels/archived_channel/archive_channel_member_spec.ts diff --git a/e2e/cypress/tests/integration/channels/archived_channel/archive_channel_operations_spec.ts b/e2e-tests/cypress/tests/integration/channels/archived_channel/archive_channel_operations_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/archived_channel/archive_channel_operations_spec.ts rename to e2e-tests/cypress/tests/integration/channels/archived_channel/archive_channel_operations_spec.ts diff --git a/e2e/cypress/tests/integration/channels/archived_channel/archive_channel_post_spec.ts b/e2e-tests/cypress/tests/integration/channels/archived_channel/archive_channel_post_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/archived_channel/archive_channel_post_spec.ts rename to e2e-tests/cypress/tests/integration/channels/archived_channel/archive_channel_post_spec.ts diff --git a/e2e/cypress/tests/integration/channels/archived_channel/archive_channel_reaction_spec.ts b/e2e-tests/cypress/tests/integration/channels/archived_channel/archive_channel_reaction_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/archived_channel/archive_channel_reaction_spec.ts rename to e2e-tests/cypress/tests/integration/channels/archived_channel/archive_channel_reaction_spec.ts diff --git a/e2e/cypress/tests/integration/channels/archived_channel/archive_channel_search_spec.ts b/e2e-tests/cypress/tests/integration/channels/archived_channel/archive_channel_search_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/archived_channel/archive_channel_search_spec.ts rename to e2e-tests/cypress/tests/integration/channels/archived_channel/archive_channel_search_spec.ts diff --git a/e2e/cypress/tests/integration/channels/archived_channel/archived_channel_spec.ts b/e2e-tests/cypress/tests/integration/channels/archived_channel/archived_channel_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/archived_channel/archived_channel_spec.ts rename to e2e-tests/cypress/tests/integration/channels/archived_channel/archived_channel_spec.ts diff --git a/e2e/cypress/tests/integration/channels/archived_channel/archived_leave_channel_spec.ts b/e2e-tests/cypress/tests/integration/channels/archived_channel/archived_leave_channel_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/archived_channel/archived_leave_channel_spec.ts rename to e2e-tests/cypress/tests/integration/channels/archived_channel/archived_leave_channel_spec.ts diff --git a/e2e/cypress/tests/integration/channels/archived_channel/helpers.ts b/e2e-tests/cypress/tests/integration/channels/archived_channel/helpers.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/archived_channel/helpers.ts rename to e2e-tests/cypress/tests/integration/channels/archived_channel/helpers.ts diff --git a/e2e/cypress/tests/integration/channels/archived_channel/join_archived_channel_spec.ts b/e2e-tests/cypress/tests/integration/channels/archived_channel/join_archived_channel_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/archived_channel/join_archived_channel_spec.ts rename to e2e-tests/cypress/tests/integration/channels/archived_channel/join_archived_channel_spec.ts diff --git a/e2e/cypress/tests/integration/channels/archived_channel/leave_archived_channel_spec.ts b/e2e-tests/cypress/tests/integration/channels/archived_channel/leave_archived_channel_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/archived_channel/leave_archived_channel_spec.ts rename to e2e-tests/cypress/tests/integration/channels/archived_channel/leave_archived_channel_spec.ts diff --git a/e2e/cypress/tests/integration/channels/archived_channel/post_menu_spec.ts b/e2e-tests/cypress/tests/integration/channels/archived_channel/post_menu_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/archived_channel/post_menu_spec.ts rename to e2e-tests/cypress/tests/integration/channels/archived_channel/post_menu_spec.ts diff --git a/e2e/cypress/tests/integration/channels/auth_sso/authentication_1_spec.ts b/e2e-tests/cypress/tests/integration/channels/auth_sso/authentication_1_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/auth_sso/authentication_1_spec.ts rename to e2e-tests/cypress/tests/integration/channels/auth_sso/authentication_1_spec.ts diff --git a/e2e/cypress/tests/integration/channels/auth_sso/authentication_2_spec.ts b/e2e-tests/cypress/tests/integration/channels/auth_sso/authentication_2_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/auth_sso/authentication_2_spec.ts rename to e2e-tests/cypress/tests/integration/channels/auth_sso/authentication_2_spec.ts diff --git a/e2e/cypress/tests/integration/channels/auth_sso/authentication_3_spec.ts b/e2e-tests/cypress/tests/integration/channels/auth_sso/authentication_3_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/auth_sso/authentication_3_spec.ts rename to e2e-tests/cypress/tests/integration/channels/auth_sso/authentication_3_spec.ts diff --git a/e2e/cypress/tests/integration/channels/auth_sso/authentication_4_spec.ts b/e2e-tests/cypress/tests/integration/channels/auth_sso/authentication_4_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/auth_sso/authentication_4_spec.ts rename to e2e-tests/cypress/tests/integration/channels/auth_sso/authentication_4_spec.ts diff --git a/e2e/cypress/tests/integration/channels/auth_sso/authentication_not_cloud_spec.ts b/e2e-tests/cypress/tests/integration/channels/auth_sso/authentication_not_cloud_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/auth_sso/authentication_not_cloud_spec.ts rename to e2e-tests/cypress/tests/integration/channels/auth_sso/authentication_not_cloud_spec.ts diff --git a/e2e/cypress/tests/integration/channels/auth_sso/hide_create_account_spec.ts b/e2e-tests/cypress/tests/integration/channels/auth_sso/hide_create_account_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/auth_sso/hide_create_account_spec.ts rename to e2e-tests/cypress/tests/integration/channels/auth_sso/hide_create_account_spec.ts diff --git a/e2e/cypress/tests/integration/channels/autocomplete/common_test.ts b/e2e-tests/cypress/tests/integration/channels/autocomplete/common_test.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/autocomplete/common_test.ts rename to e2e-tests/cypress/tests/integration/channels/autocomplete/common_test.ts diff --git a/e2e/cypress/tests/integration/channels/autocomplete/database/users_in_channel_switcher_spec.js b/e2e-tests/cypress/tests/integration/channels/autocomplete/database/users_in_channel_switcher_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/autocomplete/database/users_in_channel_switcher_spec.js rename to e2e-tests/cypress/tests/integration/channels/autocomplete/database/users_in_channel_switcher_spec.js diff --git a/e2e/cypress/tests/integration/channels/autocomplete/database/users_in_message_input_box_spec.js b/e2e-tests/cypress/tests/integration/channels/autocomplete/database/users_in_message_input_box_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/autocomplete/database/users_in_message_input_box_spec.js rename to e2e-tests/cypress/tests/integration/channels/autocomplete/database/users_in_message_input_box_spec.js diff --git a/e2e/cypress/tests/integration/channels/autocomplete/database/users_spec.js b/e2e-tests/cypress/tests/integration/channels/autocomplete/database/users_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/autocomplete/database/users_spec.js rename to e2e-tests/cypress/tests/integration/channels/autocomplete/database/users_spec.js diff --git a/e2e/cypress/tests/integration/channels/autocomplete/helpers.ts b/e2e-tests/cypress/tests/integration/channels/autocomplete/helpers.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/autocomplete/helpers.ts rename to e2e-tests/cypress/tests/integration/channels/autocomplete/helpers.ts diff --git a/e2e/cypress/tests/integration/channels/benchmark/message_spec.ts b/e2e-tests/cypress/tests/integration/channels/benchmark/message_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/benchmark/message_spec.ts rename to e2e-tests/cypress/tests/integration/channels/benchmark/message_spec.ts diff --git a/e2e/cypress/tests/integration/channels/bot_accounts/bot_api_1_spec.js b/e2e-tests/cypress/tests/integration/channels/bot_accounts/bot_api_1_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/bot_accounts/bot_api_1_spec.js rename to e2e-tests/cypress/tests/integration/channels/bot_accounts/bot_api_1_spec.js diff --git a/e2e/cypress/tests/integration/channels/bot_accounts/bot_api_2_spec.js b/e2e-tests/cypress/tests/integration/channels/bot_accounts/bot_api_2_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/bot_accounts/bot_api_2_spec.js rename to e2e-tests/cypress/tests/integration/channels/bot_accounts/bot_api_2_spec.js diff --git a/e2e/cypress/tests/integration/channels/bot_accounts/bot_api_not_cloud_spec.js b/e2e-tests/cypress/tests/integration/channels/bot_accounts/bot_api_not_cloud_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/bot_accounts/bot_api_not_cloud_spec.js rename to e2e-tests/cypress/tests/integration/channels/bot_accounts/bot_api_not_cloud_spec.js diff --git a/e2e/cypress/tests/integration/channels/bot_accounts/bot_channel_intro_spec.js b/e2e-tests/cypress/tests/integration/channels/bot_accounts/bot_channel_intro_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/bot_accounts/bot_channel_intro_spec.js rename to e2e-tests/cypress/tests/integration/channels/bot_accounts/bot_channel_intro_spec.js diff --git a/e2e/cypress/tests/integration/channels/bot_accounts/create_bot_spec.js b/e2e-tests/cypress/tests/integration/channels/bot_accounts/create_bot_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/bot_accounts/create_bot_spec.js rename to e2e-tests/cypress/tests/integration/channels/bot_accounts/create_bot_spec.js diff --git a/e2e/cypress/tests/integration/channels/bot_accounts/crud_not_cloud_spec.js b/e2e-tests/cypress/tests/integration/channels/bot_accounts/crud_not_cloud_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/bot_accounts/crud_not_cloud_spec.js rename to e2e-tests/cypress/tests/integration/channels/bot_accounts/crud_not_cloud_spec.js diff --git a/e2e/cypress/tests/integration/channels/bot_accounts/crud_spec.js b/e2e-tests/cypress/tests/integration/channels/bot_accounts/crud_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/bot_accounts/crud_spec.js rename to e2e-tests/cypress/tests/integration/channels/bot_accounts/crud_spec.js diff --git a/e2e/cypress/tests/integration/channels/bot_accounts/display_name_spec.js b/e2e-tests/cypress/tests/integration/channels/bot_accounts/display_name_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/bot_accounts/display_name_spec.js rename to e2e-tests/cypress/tests/integration/channels/bot_accounts/display_name_spec.js diff --git a/e2e/cypress/tests/integration/channels/bot_accounts/edit_bot_spec.js b/e2e-tests/cypress/tests/integration/channels/bot_accounts/edit_bot_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/bot_accounts/edit_bot_spec.js rename to e2e-tests/cypress/tests/integration/channels/bot_accounts/edit_bot_spec.js diff --git a/e2e/cypress/tests/integration/channels/bot_accounts/edit_bot_username_spec.js b/e2e-tests/cypress/tests/integration/channels/bot_accounts/edit_bot_username_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/bot_accounts/edit_bot_username_spec.js rename to e2e-tests/cypress/tests/integration/channels/bot_accounts/edit_bot_username_spec.js diff --git a/e2e/cypress/tests/integration/channels/bot_accounts/helpers.js b/e2e-tests/cypress/tests/integration/channels/bot_accounts/helpers.js similarity index 100% rename from e2e/cypress/tests/integration/channels/bot_accounts/helpers.js rename to e2e-tests/cypress/tests/integration/channels/bot_accounts/helpers.js diff --git a/e2e/cypress/tests/integration/channels/bot_accounts/in_lists_1_spec.js b/e2e-tests/cypress/tests/integration/channels/bot_accounts/in_lists_1_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/bot_accounts/in_lists_1_spec.js rename to e2e-tests/cypress/tests/integration/channels/bot_accounts/in_lists_1_spec.js diff --git a/e2e/cypress/tests/integration/channels/bot_accounts/in_lists_2_spec.js b/e2e-tests/cypress/tests/integration/channels/bot_accounts/in_lists_2_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/bot_accounts/in_lists_2_spec.js rename to e2e-tests/cypress/tests/integration/channels/bot_accounts/in_lists_2_spec.js diff --git a/e2e/cypress/tests/integration/channels/bot_accounts/in_teams_and_channels_spec.js b/e2e-tests/cypress/tests/integration/channels/bot_accounts/in_teams_and_channels_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/bot_accounts/in_teams_and_channels_spec.js rename to e2e-tests/cypress/tests/integration/channels/bot_accounts/in_teams_and_channels_spec.js diff --git a/e2e/cypress/tests/integration/channels/bot_accounts/managing_bot_accounts_not_cloud_spec.js b/e2e-tests/cypress/tests/integration/channels/bot_accounts/managing_bot_accounts_not_cloud_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/bot_accounts/managing_bot_accounts_not_cloud_spec.js rename to e2e-tests/cypress/tests/integration/channels/bot_accounts/managing_bot_accounts_not_cloud_spec.js diff --git a/e2e/cypress/tests/integration/channels/bot_accounts/managing_bot_accounts_spec.js b/e2e-tests/cypress/tests/integration/channels/bot_accounts/managing_bot_accounts_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/bot_accounts/managing_bot_accounts_spec.js rename to e2e-tests/cypress/tests/integration/channels/bot_accounts/managing_bot_accounts_spec.js diff --git a/e2e/cypress/tests/integration/channels/bot_accounts/post_message_spec.js b/e2e-tests/cypress/tests/integration/channels/bot_accounts/post_message_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/bot_accounts/post_message_spec.js rename to e2e-tests/cypress/tests/integration/channels/bot_accounts/post_message_spec.js diff --git a/e2e/cypress/tests/integration/channels/bot_accounts/promote_demote_spec.js b/e2e-tests/cypress/tests/integration/channels/bot_accounts/promote_demote_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/bot_accounts/promote_demote_spec.js rename to e2e-tests/cypress/tests/integration/channels/bot_accounts/promote_demote_spec.js diff --git a/e2e/cypress/tests/integration/channels/bot_accounts/sidebar_display_spec.js b/e2e-tests/cypress/tests/integration/channels/bot_accounts/sidebar_display_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/bot_accounts/sidebar_display_spec.js rename to e2e-tests/cypress/tests/integration/channels/bot_accounts/sidebar_display_spec.js diff --git a/e2e/cypress/tests/integration/channels/bot_accounts/tags_spec.js b/e2e-tests/cypress/tests/integration/channels/bot_accounts/tags_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/bot_accounts/tags_spec.js rename to e2e-tests/cypress/tests/integration/channels/bot_accounts/tags_spec.js diff --git a/e2e/cypress/tests/integration/channels/channel/archived_channels_1_spec.js b/e2e-tests/cypress/tests/integration/channels/channel/archived_channels_1_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/channel/archived_channels_1_spec.js rename to e2e-tests/cypress/tests/integration/channels/channel/archived_channels_1_spec.js diff --git a/e2e/cypress/tests/integration/channels/channel/archived_channels_2_spec.js b/e2e-tests/cypress/tests/integration/channels/channel/archived_channels_2_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/channel/archived_channels_2_spec.js rename to e2e-tests/cypress/tests/integration/channels/channel/archived_channels_2_spec.js diff --git a/e2e/cypress/tests/integration/channels/channel/channel_info_rhs_spec.js b/e2e-tests/cypress/tests/integration/channels/channel/channel_info_rhs_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/channel/channel_info_rhs_spec.js rename to e2e-tests/cypress/tests/integration/channels/channel/channel_info_rhs_spec.js diff --git a/e2e/cypress/tests/integration/channels/channel/channel_members_rhs_spec.js b/e2e-tests/cypress/tests/integration/channels/channel/channel_members_rhs_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/channel/channel_members_rhs_spec.js rename to e2e-tests/cypress/tests/integration/channels/channel/channel_members_rhs_spec.js diff --git a/e2e/cypress/tests/integration/channels/channel/channel_mention_autocomplete_spec.js b/e2e-tests/cypress/tests/integration/channels/channel/channel_mention_autocomplete_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/channel/channel_mention_autocomplete_spec.js rename to e2e-tests/cypress/tests/integration/channels/channel/channel_mention_autocomplete_spec.js diff --git a/e2e/cypress/tests/integration/channels/channel/channel_name_tooltips_spec.js b/e2e-tests/cypress/tests/integration/channels/channel/channel_name_tooltips_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/channel/channel_name_tooltips_spec.js rename to e2e-tests/cypress/tests/integration/channels/channel/channel_name_tooltips_spec.js diff --git a/e2e/cypress/tests/integration/channels/channel/channel_routing_spec.js b/e2e-tests/cypress/tests/integration/channels/channel/channel_routing_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/channel/channel_routing_spec.js rename to e2e-tests/cypress/tests/integration/channels/channel/channel_routing_spec.js diff --git a/e2e/cypress/tests/integration/channels/channel/channel_settings_spec.js b/e2e-tests/cypress/tests/integration/channels/channel/channel_settings_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/channel/channel_settings_spec.js rename to e2e-tests/cypress/tests/integration/channels/channel/channel_settings_spec.js diff --git a/e2e/cypress/tests/integration/channels/channel/channel_switcher_spec.js b/e2e-tests/cypress/tests/integration/channels/channel/channel_switcher_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/channel/channel_switcher_spec.js rename to e2e-tests/cypress/tests/integration/channels/channel/channel_switcher_spec.js diff --git a/e2e/cypress/tests/integration/channels/channel/close_direct_group_spec.js b/e2e-tests/cypress/tests/integration/channels/channel/close_direct_group_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/channel/close_direct_group_spec.js rename to e2e-tests/cypress/tests/integration/channels/channel/close_direct_group_spec.js diff --git a/e2e/cypress/tests/integration/channels/channel/convert_channel_to_private_spec.js b/e2e-tests/cypress/tests/integration/channels/channel/convert_channel_to_private_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/channel/convert_channel_to_private_spec.js rename to e2e-tests/cypress/tests/integration/channels/channel/convert_channel_to_private_spec.js diff --git a/e2e/cypress/tests/integration/channels/channel/leave_and_archive_channel_destructive_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel/leave_and_archive_channel_destructive_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel/leave_and_archive_channel_destructive_spec.ts rename to e2e-tests/cypress/tests/integration/channels/channel/leave_and_archive_channel_destructive_spec.ts diff --git a/e2e/cypress/tests/integration/channels/channel/leave_channel_spec.js b/e2e-tests/cypress/tests/integration/channels/channel/leave_channel_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/channel/leave_channel_spec.js rename to e2e-tests/cypress/tests/integration/channels/channel/leave_channel_spec.js diff --git a/e2e/cypress/tests/integration/channels/channel/more_channels_spec.js b/e2e-tests/cypress/tests/integration/channels/channel/more_channels_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/channel/more_channels_spec.js rename to e2e-tests/cypress/tests/integration/channels/channel/more_channels_spec.js diff --git a/e2e/cypress/tests/integration/channels/channel/more_public_channels_spec.js b/e2e-tests/cypress/tests/integration/channels/channel/more_public_channels_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/channel/more_public_channels_spec.js rename to e2e-tests/cypress/tests/integration/channels/channel/more_public_channels_spec.js diff --git a/e2e/cypress/tests/integration/channels/channel/new_channel_with_board_spec.js b/e2e-tests/cypress/tests/integration/channels/channel/new_channel_with_board_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/channel/new_channel_with_board_spec.js rename to e2e-tests/cypress/tests/integration/channels/channel/new_channel_with_board_spec.js diff --git a/e2e/cypress/tests/integration/channels/channel/open_rhs_coming_from_system_console_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel/open_rhs_coming_from_system_console_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel/open_rhs_coming_from_system_console_spec.ts rename to e2e-tests/cypress/tests/integration/channels/channel/open_rhs_coming_from_system_console_spec.ts diff --git a/e2e/cypress/tests/integration/channels/channel/user_to_admin_updates_manage_channel_members_rhs_spec.js b/e2e-tests/cypress/tests/integration/channels/channel/user_to_admin_updates_manage_channel_members_rhs_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/channel/user_to_admin_updates_manage_channel_members_rhs_spec.js rename to e2e-tests/cypress/tests/integration/channels/channel/user_to_admin_updates_manage_channel_members_rhs_spec.js diff --git a/e2e/cypress/tests/integration/channels/channel/user_to_channel_admin_member_updates_manage_channel_members_rhs_spec.js b/e2e-tests/cypress/tests/integration/channels/channel/user_to_channel_admin_member_updates_manage_channel_members_rhs_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/channel/user_to_channel_admin_member_updates_manage_channel_members_rhs_spec.js rename to e2e-tests/cypress/tests/integration/channels/channel/user_to_channel_admin_member_updates_manage_channel_members_rhs_spec.js diff --git a/e2e/cypress/tests/integration/channels/channel_settings/add_users_to_channel_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_settings/add_users_to_channel_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel_settings/add_users_to_channel_spec.ts rename to e2e-tests/cypress/tests/integration/channels/channel_settings/add_users_to_channel_spec.ts diff --git a/e2e/cypress/tests/integration/channels/channel_settings/channel_header_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_settings/channel_header_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel_settings/channel_header_spec.ts rename to e2e-tests/cypress/tests/integration/channels/channel_settings/channel_header_spec.ts diff --git a/e2e/cypress/tests/integration/channels/channel_settings/channel_name_validations_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_settings/channel_name_validations_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel_settings/channel_name_validations_spec.ts rename to e2e-tests/cypress/tests/integration/channels/channel_settings/channel_name_validations_spec.ts diff --git a/e2e/cypress/tests/integration/channels/channel_settings/more_unreads_position_with_scroll_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_settings/more_unreads_position_with_scroll_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel_settings/more_unreads_position_with_scroll_spec.ts rename to e2e-tests/cypress/tests/integration/channels/channel_settings/more_unreads_position_with_scroll_spec.ts diff --git a/e2e/cypress/tests/integration/channels/channel_sidebar/category.d.ts b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/category.d.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel_sidebar/category.d.ts rename to e2e-tests/cypress/tests/integration/channels/channel_sidebar/category.d.ts diff --git a/e2e/cypress/tests/integration/channels/channel_sidebar/category_collapsing_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/category_collapsing_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel_sidebar/category_collapsing_spec.ts rename to e2e-tests/cypress/tests/integration/channels/channel_sidebar/category_collapsing_spec.ts diff --git a/e2e/cypress/tests/integration/channels/channel_sidebar/category_muting_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/category_muting_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel_sidebar/category_muting_spec.ts rename to e2e-tests/cypress/tests/integration/channels/channel_sidebar/category_muting_spec.ts diff --git a/e2e/cypress/tests/integration/channels/channel_sidebar/category_sorting_1_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/category_sorting_1_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel_sidebar/category_sorting_1_spec.ts rename to e2e-tests/cypress/tests/integration/channels/channel_sidebar/category_sorting_1_spec.ts diff --git a/e2e/cypress/tests/integration/channels/channel_sidebar/category_sorting_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/category_sorting_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel_sidebar/category_sorting_spec.ts rename to e2e-tests/cypress/tests/integration/channels/channel_sidebar/category_sorting_spec.ts diff --git a/e2e/cypress/tests/integration/channels/channel_sidebar/channel_sidebar_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/channel_sidebar_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel_sidebar/channel_sidebar_spec.ts rename to e2e-tests/cypress/tests/integration/channels/channel_sidebar/channel_sidebar_spec.ts diff --git a/e2e/cypress/tests/integration/channels/channel_sidebar/custom_categories_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/custom_categories_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel_sidebar/custom_categories_spec.ts rename to e2e-tests/cypress/tests/integration/channels/channel_sidebar/custom_categories_spec.ts diff --git a/e2e/cypress/tests/integration/channels/channel_sidebar/dm_category_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/dm_category_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel_sidebar/dm_category_spec.ts rename to e2e-tests/cypress/tests/integration/channels/channel_sidebar/dm_category_spec.ts diff --git a/e2e/cypress/tests/integration/channels/channel_sidebar/dm_gm_behaviour_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/dm_gm_behaviour_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel_sidebar/dm_gm_behaviour_spec.ts rename to e2e-tests/cypress/tests/integration/channels/channel_sidebar/dm_gm_behaviour_spec.ts diff --git a/e2e/cypress/tests/integration/channels/channel_sidebar/dm_gm_filtering_sorting_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/dm_gm_filtering_sorting_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel_sidebar/dm_gm_filtering_sorting_spec.ts rename to e2e-tests/cypress/tests/integration/channels/channel_sidebar/dm_gm_filtering_sorting_spec.ts diff --git a/e2e/cypress/tests/integration/channels/channel_sidebar/dm_sidebar_not_remove_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/dm_sidebar_not_remove_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel_sidebar/dm_sidebar_not_remove_spec.ts rename to e2e-tests/cypress/tests/integration/channels/channel_sidebar/dm_sidebar_not_remove_spec.ts diff --git a/e2e/cypress/tests/integration/channels/channel_sidebar/drag_and_drop_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/drag_and_drop_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel_sidebar/drag_and_drop_spec.ts rename to e2e-tests/cypress/tests/integration/channels/channel_sidebar/drag_and_drop_spec.ts diff --git a/e2e/cypress/tests/integration/channels/channel_sidebar/group_unreads_separately_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/group_unreads_separately_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel_sidebar/group_unreads_separately_spec.ts rename to e2e-tests/cypress/tests/integration/channels/channel_sidebar/group_unreads_separately_spec.ts diff --git a/e2e/cypress/tests/integration/channels/channel_sidebar/helpers.ts b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/helpers.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel_sidebar/helpers.ts rename to e2e-tests/cypress/tests/integration/channels/channel_sidebar/helpers.ts diff --git a/e2e/cypress/tests/integration/channels/channel_sidebar/history_channel_switcher_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/history_channel_switcher_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel_sidebar/history_channel_switcher_spec.ts rename to e2e-tests/cypress/tests/integration/channels/channel_sidebar/history_channel_switcher_spec.ts diff --git a/e2e/cypress/tests/integration/channels/channel_sidebar/hotkeys_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/hotkeys_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel_sidebar/hotkeys_spec.ts rename to e2e-tests/cypress/tests/integration/channels/channel_sidebar/hotkeys_spec.ts diff --git a/e2e/cypress/tests/integration/channels/channel_sidebar/new_category_badge_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/new_category_badge_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel_sidebar/new_category_badge_spec.ts rename to e2e-tests/cypress/tests/integration/channels/channel_sidebar/new_category_badge_spec.ts diff --git a/e2e/cypress/tests/integration/channels/channel_sidebar/new_channel_dropdown_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/new_channel_dropdown_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel_sidebar/new_channel_dropdown_spec.ts rename to e2e-tests/cypress/tests/integration/channels/channel_sidebar/new_channel_dropdown_spec.ts diff --git a/e2e/cypress/tests/integration/channels/channel_sidebar/sidebar_category_menu_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/sidebar_category_menu_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel_sidebar/sidebar_category_menu_spec.ts rename to e2e-tests/cypress/tests/integration/channels/channel_sidebar/sidebar_category_menu_spec.ts diff --git a/e2e/cypress/tests/integration/channels/channel_sidebar/sidebar_channel_menu_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/sidebar_channel_menu_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel_sidebar/sidebar_channel_menu_spec.ts rename to e2e-tests/cypress/tests/integration/channels/channel_sidebar/sidebar_channel_menu_spec.ts diff --git a/e2e/cypress/tests/integration/channels/channel_sidebar/unread_filter_spec.ts b/e2e-tests/cypress/tests/integration/channels/channel_sidebar/unread_filter_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/channel_sidebar/unread_filter_spec.ts rename to e2e-tests/cypress/tests/integration/channels/channel_sidebar/unread_filter_spec.ts diff --git a/e2e/cypress/tests/integration/channels/collapsed_reply_threads/channel_notifications_spec.js b/e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/channel_notifications_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/collapsed_reply_threads/channel_notifications_spec.js rename to e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/channel_notifications_spec.js diff --git a/e2e/cypress/tests/integration/channels/collapsed_reply_threads/crt_settings_spec.js b/e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/crt_settings_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/collapsed_reply_threads/crt_settings_spec.js rename to e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/crt_settings_spec.js diff --git a/e2e/cypress/tests/integration/channels/collapsed_reply_threads/crt_tour_spec.js b/e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/crt_tour_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/collapsed_reply_threads/crt_tour_spec.js rename to e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/crt_tour_spec.js diff --git a/e2e/cypress/tests/integration/channels/collapsed_reply_threads/files_1_spec.js b/e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/files_1_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/collapsed_reply_threads/files_1_spec.js rename to e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/files_1_spec.js diff --git a/e2e/cypress/tests/integration/channels/collapsed_reply_threads/files_spec.js b/e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/files_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/collapsed_reply_threads/files_spec.js rename to e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/files_spec.js diff --git a/e2e/cypress/tests/integration/channels/collapsed_reply_threads/following_spec.js b/e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/following_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/collapsed_reply_threads/following_spec.js rename to e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/following_spec.js diff --git a/e2e/cypress/tests/integration/channels/collapsed_reply_threads/global_threads_spec.js b/e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/global_threads_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/collapsed_reply_threads/global_threads_spec.js rename to e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/global_threads_spec.js diff --git a/e2e/cypress/tests/integration/channels/collapsed_reply_threads/last_viewed_spec.js b/e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/last_viewed_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/collapsed_reply_threads/last_viewed_spec.js rename to e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/last_viewed_spec.js diff --git a/e2e/cypress/tests/integration/channels/collapsed_reply_threads/replies_spec.js b/e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/replies_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/collapsed_reply_threads/replies_spec.js rename to e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/replies_spec.js diff --git a/e2e/cypress/tests/integration/channels/collapsed_reply_threads/unread_spec.js b/e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/unread_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/collapsed_reply_threads/unread_spec.js rename to e2e-tests/cypress/tests/integration/channels/collapsed_reply_threads/unread_spec.js diff --git a/e2e/cypress/tests/integration/channels/commands/leave_channel_spec.ts b/e2e-tests/cypress/tests/integration/channels/commands/leave_channel_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/commands/leave_channel_spec.ts rename to e2e-tests/cypress/tests/integration/channels/commands/leave_channel_spec.ts diff --git a/e2e/cypress/tests/integration/channels/custom_status/custom_status_1_spec.ts b/e2e-tests/cypress/tests/integration/channels/custom_status/custom_status_1_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/custom_status/custom_status_1_spec.ts rename to e2e-tests/cypress/tests/integration/channels/custom_status/custom_status_1_spec.ts diff --git a/e2e/cypress/tests/integration/channels/custom_status/custom_status_2_spec.ts b/e2e-tests/cypress/tests/integration/channels/custom_status/custom_status_2_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/custom_status/custom_status_2_spec.ts rename to e2e-tests/cypress/tests/integration/channels/custom_status/custom_status_2_spec.ts diff --git a/e2e/cypress/tests/integration/channels/custom_status/custom_status_3_spec.ts b/e2e-tests/cypress/tests/integration/channels/custom_status/custom_status_3_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/custom_status/custom_status_3_spec.ts rename to e2e-tests/cypress/tests/integration/channels/custom_status/custom_status_3_spec.ts diff --git a/e2e/cypress/tests/integration/channels/custom_status/custom_status_4_spec.ts b/e2e-tests/cypress/tests/integration/channels/custom_status/custom_status_4_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/custom_status/custom_status_4_spec.ts rename to e2e-tests/cypress/tests/integration/channels/custom_status/custom_status_4_spec.ts diff --git a/e2e/cypress/tests/integration/channels/custom_status/custom_status_5_spec.ts b/e2e-tests/cypress/tests/integration/channels/custom_status/custom_status_5_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/custom_status/custom_status_5_spec.ts rename to e2e-tests/cypress/tests/integration/channels/custom_status/custom_status_5_spec.ts diff --git a/e2e/cypress/tests/integration/channels/custom_status/custom_status_6_spec.ts b/e2e-tests/cypress/tests/integration/channels/custom_status/custom_status_6_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/custom_status/custom_status_6_spec.ts rename to e2e-tests/cypress/tests/integration/channels/custom_status/custom_status_6_spec.ts diff --git a/e2e/cypress/tests/integration/channels/custom_status/custom_status_expiry/custom_status_expiry_1_spec.ts b/e2e-tests/cypress/tests/integration/channels/custom_status/custom_status_expiry/custom_status_expiry_1_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/custom_status/custom_status_expiry/custom_status_expiry_1_spec.ts rename to e2e-tests/cypress/tests/integration/channels/custom_status/custom_status_expiry/custom_status_expiry_1_spec.ts diff --git a/e2e/cypress/tests/integration/channels/custom_status/custom_status_expiry/custom_status_expiry_2_spec.ts b/e2e-tests/cypress/tests/integration/channels/custom_status/custom_status_expiry/custom_status_expiry_2_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/custom_status/custom_status_expiry/custom_status_expiry_2_spec.ts rename to e2e-tests/cypress/tests/integration/channels/custom_status/custom_status_expiry/custom_status_expiry_2_spec.ts diff --git a/e2e/cypress/tests/integration/channels/custom_status/custom_status_expiry/custom_status_expiry_3_spec.ts b/e2e-tests/cypress/tests/integration/channels/custom_status/custom_status_expiry/custom_status_expiry_3_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/custom_status/custom_status_expiry/custom_status_expiry_3_spec.ts rename to e2e-tests/cypress/tests/integration/channels/custom_status/custom_status_expiry/custom_status_expiry_3_spec.ts diff --git a/e2e/cypress/tests/integration/channels/custom_status/custom_status_expiry/custom_status_expiry_4_spec.ts b/e2e-tests/cypress/tests/integration/channels/custom_status/custom_status_expiry/custom_status_expiry_4_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/custom_status/custom_status_expiry/custom_status_expiry_4_spec.ts rename to e2e-tests/cypress/tests/integration/channels/custom_status/custom_status_expiry/custom_status_expiry_4_spec.ts diff --git a/e2e/cypress/tests/integration/channels/emoji/custom_emoji_1_1_spec.ts b/e2e-tests/cypress/tests/integration/channels/emoji/custom_emoji_1_1_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/emoji/custom_emoji_1_1_spec.ts rename to e2e-tests/cypress/tests/integration/channels/emoji/custom_emoji_1_1_spec.ts diff --git a/e2e/cypress/tests/integration/channels/emoji/custom_emoji_1_spec.ts b/e2e-tests/cypress/tests/integration/channels/emoji/custom_emoji_1_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/emoji/custom_emoji_1_spec.ts rename to e2e-tests/cypress/tests/integration/channels/emoji/custom_emoji_1_spec.ts diff --git a/e2e/cypress/tests/integration/channels/emoji/custom_emoji_2_1_spec.ts b/e2e-tests/cypress/tests/integration/channels/emoji/custom_emoji_2_1_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/emoji/custom_emoji_2_1_spec.ts rename to e2e-tests/cypress/tests/integration/channels/emoji/custom_emoji_2_1_spec.ts diff --git a/e2e/cypress/tests/integration/channels/emoji/custom_emoji_2_spec.ts b/e2e-tests/cypress/tests/integration/channels/emoji/custom_emoji_2_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/emoji/custom_emoji_2_spec.ts rename to e2e-tests/cypress/tests/integration/channels/emoji/custom_emoji_2_spec.ts diff --git a/e2e/cypress/tests/integration/channels/emoji/custom_emoji_3_spec.ts b/e2e-tests/cypress/tests/integration/channels/emoji/custom_emoji_3_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/emoji/custom_emoji_3_spec.ts rename to e2e-tests/cypress/tests/integration/channels/emoji/custom_emoji_3_spec.ts diff --git a/e2e/cypress/tests/integration/channels/emoji/helpers.js b/e2e-tests/cypress/tests/integration/channels/emoji/helpers.js similarity index 100% rename from e2e/cypress/tests/integration/channels/emoji/helpers.js rename to e2e-tests/cypress/tests/integration/channels/emoji/helpers.js diff --git a/e2e/cypress/tests/integration/channels/emoji/recently_used_emoji_1_spec.ts b/e2e-tests/cypress/tests/integration/channels/emoji/recently_used_emoji_1_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/emoji/recently_used_emoji_1_spec.ts rename to e2e-tests/cypress/tests/integration/channels/emoji/recently_used_emoji_1_spec.ts diff --git a/e2e/cypress/tests/integration/channels/emoji/recently_used_emoji_2_spec.ts b/e2e-tests/cypress/tests/integration/channels/emoji/recently_used_emoji_2_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/emoji/recently_used_emoji_2_spec.ts rename to e2e-tests/cypress/tests/integration/channels/emoji/recently_used_emoji_2_spec.ts diff --git a/e2e/cypress/tests/integration/channels/emoji/sorted_emojis_spec.ts b/e2e-tests/cypress/tests/integration/channels/emoji/sorted_emojis_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/emoji/sorted_emojis_spec.ts rename to e2e-tests/cypress/tests/integration/channels/emoji/sorted_emojis_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/accessibility/accessibility_input_fields_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/accessibility/accessibility_input_fields_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/accessibility/accessibility_input_fields_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/accessibility/accessibility_input_fields_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/accessibility/accessibility_modals_dialogs_1_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/accessibility/accessibility_modals_dialogs_1_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/accessibility/accessibility_modals_dialogs_1_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/accessibility/accessibility_modals_dialogs_1_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/accessibility/accessibility_modals_dialogs_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/accessibility/accessibility_modals_dialogs_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/accessibility/accessibility_modals_dialogs_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/accessibility/accessibility_modals_dialogs_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/auth_sso/authentication_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/auth_sso/authentication_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/auth_sso/authentication_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/auth_sso/authentication_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/auth_sso/mfa_authentication_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/auth_sso/mfa_authentication_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/auth_sso/mfa_authentication_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/auth_sso/mfa_authentication_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/bot_accounts/managing_bot_accounts_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/bot_accounts/managing_bot_accounts_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/bot_accounts/managing_bot_accounts_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/bot_accounts/managing_bot_accounts_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/channel/channel_groups_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/channel/channel_groups_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/channel/channel_groups_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/channel/channel_groups_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/cloud/billing/after_subscription_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/cloud/billing/after_subscription_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/cloud/billing/after_subscription_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/cloud/billing/after_subscription_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/cloud/billing/billing_history_free_trial_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/cloud/billing/billing_history_free_trial_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/cloud/billing/billing_history_free_trial_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/cloud/billing/billing_history_free_trial_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/cloud/billing/cloud_pricing_modal_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/cloud/billing/cloud_pricing_modal_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/cloud/billing/cloud_pricing_modal_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/cloud/billing/cloud_pricing_modal_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/cloud/billing/company_information_free_trial_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/cloud/billing/company_information_free_trial_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/cloud/billing/company_information_free_trial_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/cloud/billing/company_information_free_trial_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/cloud/billing/downgrade_feedback_modal_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/cloud/billing/downgrade_feedback_modal_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/cloud/billing/downgrade_feedback_modal_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/cloud/billing/downgrade_feedback_modal_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/cloud/billing/notify_admin_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/cloud/billing/notify_admin_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/cloud/billing/notify_admin_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/cloud/billing/notify_admin_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/cloud/billing/payment_free_trial_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/cloud/billing/payment_free_trial_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/cloud/billing/payment_free_trial_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/cloud/billing/payment_free_trial_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/cloud/billing/subscriptions_free_trial_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/cloud/billing/subscriptions_free_trial_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/cloud/billing/subscriptions_free_trial_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/cloud/billing/subscriptions_free_trial_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/cloud/billing/yearly_subscription_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/cloud/billing/yearly_subscription_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/cloud/billing/yearly_subscription_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/cloud/billing/yearly_subscription_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/channels_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/channels_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/channels_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/channels_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/channels_with_special_characters_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/channels_with_special_characters_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/channels_with_special_characters_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/channels_with_special_characters_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/helpers/index.js b/e2e-tests/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/helpers/index.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/helpers/index.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/helpers/index.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/renaming_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/renaming_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/renaming_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/renaming_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/renaming_team_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/renaming_team_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/renaming_team_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/renaming_team_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/system_console_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/system_console_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/system_console_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/system_console_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/users_in_channel_switcher_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/users_in_channel_switcher_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/users_in_channel_switcher_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/users_in_channel_switcher_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/users_in_message_input_box_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/users_in_message_input_box_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/users_in_message_input_box_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/users_in_message_input_box_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/users_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/users_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/users_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/elasticsearch_autocomplete/users_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/extend_session/email_login_activity_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/extend_session/email_login_activity_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/extend_session/email_login_activity_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/extend_session/email_login_activity_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/extend_session/not_extended_when_disabled/helpers.js b/e2e-tests/cypress/tests/integration/channels/enterprise/extend_session/not_extended_when_disabled/helpers.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/extend_session/not_extended_when_disabled/helpers.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/extend_session/not_extended_when_disabled/helpers.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/extend_session/not_extended_when_disabled/with_email_login_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/extend_session/not_extended_when_disabled/with_email_login_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/extend_session/not_extended_when_disabled/with_email_login_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/extend_session/not_extended_when_disabled/with_email_login_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/extend_session/not_extended_when_disabled/with_ldap_login_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/extend_session/not_extended_when_disabled/with_ldap_login_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/extend_session/not_extended_when_disabled/with_ldap_login_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/extend_session/not_extended_when_disabled/with_ldap_login_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/extend_session/not_extended_when_disabled/with_saml_login_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/extend_session/not_extended_when_disabled/with_saml_login_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/extend_session/not_extended_when_disabled/with_saml_login_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/extend_session/not_extended_when_disabled/with_saml_login_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/extend_session/session_length_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/extend_session/session_length_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/extend_session/session_length_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/extend_session/session_length_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/group_mentions/group_mentions_permissions_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/group_mentions/group_mentions_permissions_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/group_mentions/group_mentions_permissions_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/group_mentions/group_mentions_permissions_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/group_mentions/group_mentions_posts_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/group_mentions/group_mentions_posts_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/group_mentions/group_mentions_posts_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/group_mentions/group_mentions_posts_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/group_mentions/group_mentions_system_messages_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/group_mentions/group_mentions_system_messages_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/group_mentions/group_mentions_system_messages_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/group_mentions/group_mentions_system_messages_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/group_mentions/helpers.js b/e2e-tests/cypress/tests/integration/channels/enterprise/group_mentions/helpers.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/group_mentions/helpers.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/group_mentions/helpers.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/guest_accounts/guest_add_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_add_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/guest_accounts/guest_add_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_add_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/guest_accounts/guest_experience_ui_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_experience_ui_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/guest_accounts/guest_experience_ui_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_experience_ui_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/guest_accounts/guest_feature_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_feature_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/guest_accounts/guest_feature_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_feature_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/guest_accounts/guest_identification_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_identification_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/guest_accounts/guest_identification_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_identification_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/guest_accounts/guest_identification_ui_not_cloud_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_identification_ui_not_cloud_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/guest_accounts/guest_identification_ui_not_cloud_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_identification_ui_not_cloud_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/guest_accounts/guest_identification_ui_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_identification_ui_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/guest_accounts/guest_identification_ui_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_identification_ui_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/guest_accounts/guest_invitation_ui_more_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_invitation_ui_more_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/guest_accounts/guest_invitation_ui_more_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_invitation_ui_more_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/guest_accounts/guest_invitation_ui_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_invitation_ui_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/guest_accounts/guest_invitation_ui_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_invitation_ui_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/guest_accounts/guest_popover_ui_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_popover_ui_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/guest_accounts/guest_popover_ui_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_popover_ui_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/guest_accounts/guest_removal_ui_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_removal_ui_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/guest_accounts/guest_removal_ui_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/guest_removal_ui_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/guest_accounts/helpers.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/helpers.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/guest_accounts/helpers.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/helpers.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/guest_accounts/member_invitation_ui_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/member_invitation_ui_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/guest_accounts/member_invitation_ui_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/member_invitation_ui_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/guest_accounts/system_console_guest_access_ui_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/system_console_guest_access_ui_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/guest_accounts/system_console_guest_access_ui_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/system_console_guest_access_ui_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/guest_accounts/system_console_manage_guest_not_cloud_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/system_console_manage_guest_not_cloud_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/guest_accounts/system_console_manage_guest_not_cloud_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/system_console_manage_guest_not_cloud_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/guest_accounts/system_console_manage_guest_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/system_console_manage_guest_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/guest_accounts/system_console_manage_guest_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/guest_accounts/system_console_manage_guest_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/integrations/incoming_webhook_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/integrations/incoming_webhook_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/integrations/incoming_webhook_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/integrations/incoming_webhook_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/ldap/ldap_group_sync_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/ldap/ldap_group_sync_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/ldap/ldap_group_sync_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/ldap/ldap_group_sync_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/ldap/ldap_guest_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/ldap/ldap_guest_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/ldap/ldap_guest_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/ldap/ldap_guest_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/ldap/ldap_login_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/ldap/ldap_login_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/ldap/ldap_login_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/ldap/ldap_login_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/ldap/ldap_setting_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/ldap/ldap_setting_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/ldap/ldap_setting_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/ldap/ldap_setting_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/ldap_group/channel_modes_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/ldap_group/channel_modes_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/ldap_group/channel_modes_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/ldap_group/channel_modes_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/ldap_group/group_mentions_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/ldap_group/group_mentions_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/ldap_group/group_mentions_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/ldap_group/group_mentions_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/ldap_group/groups_assign_roles_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/ldap_group/groups_assign_roles_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/ldap_group/groups_assign_roles_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/ldap_group/groups_assign_roles_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/ldap_group/invite_bot_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/ldap_group/invite_bot_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/ldap_group/invite_bot_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/ldap_group/invite_bot_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/ldap_group/search_channels_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/ldap_group/search_channels_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/ldap_group/search_channels_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/ldap_group/search_channels_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/ldap_group/team_and_channel_assign_roles_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/ldap_group/team_and_channel_assign_roles_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/ldap_group/team_and_channel_assign_roles_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/ldap_group/team_and_channel_assign_roles_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/oauth/oauth_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/oauth/oauth_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/oauth/oauth_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/oauth/oauth_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/permissions/team_permissions_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/permissions/team_permissions_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/permissions/team_permissions_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/permissions/team_permissions_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/profile_popover/profile_popover_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/profile_popover/profile_popover_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/profile_popover/profile_popover_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/profile_popover/profile_popover_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/profile_popover/profile_popover_spec_user_a_b_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/profile_popover/profile_popover_spec_user_a_b_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/profile_popover/profile_popover_spec_user_a_b_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/profile_popover/profile_popover_spec_user_a_b_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/saml/okta_login_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/saml/okta_login_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/saml/okta_login_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/saml/okta_login_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/saml/saml_automated_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/saml/saml_automated_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/saml/saml_automated_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/saml/saml_automated_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/saml/saml_guest_member_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/saml/saml_guest_member_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/saml/saml_guest_member_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/saml/saml_guest_member_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/saml/saml_metadata_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/saml/saml_metadata_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/saml/saml_metadata_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/saml/saml_metadata_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/self-hosted/self_hosted_pricing_modal_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/self-hosted/self_hosted_pricing_modal_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/self-hosted/self_hosted_pricing_modal_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/self-hosted/self_hosted_pricing_modal_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/self-hosted/self_hosted_purchase_spec.ts b/e2e-tests/cypress/tests/integration/channels/enterprise/self-hosted/self_hosted_purchase_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/self-hosted/self_hosted_purchase_spec.ts rename to e2e-tests/cypress/tests/integration/channels/enterprise/self-hosted/self_hosted_purchase_spec.ts diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/about/edition_and_license_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/about/edition_and_license_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/about/edition_and_license_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/about/edition_and_license_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/about/starter_edition_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/about/starter_edition_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/about/starter_edition_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/about/starter_edition_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/archived_channels_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/archived_channels_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/archived_channels_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/archived_channels_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/authentication_method_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/authentication_method_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/authentication_method_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/authentication_method_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/channel_members_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/channel_members_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/channel_members_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/channel_members_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/channel_mentions_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/channel_mentions_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/channel_mentions_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/channel_mentions_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/constants.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/constants.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/constants.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/constants.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/create_posts_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/create_posts_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/create_posts_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/create_posts_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/helpers.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/helpers.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/helpers.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/helpers.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/higher_scoped_scheme_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/higher_scoped_scheme_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/higher_scoped_scheme_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/higher_scoped_scheme_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/manage_members_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/manage_members_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/manage_members_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/manage_members_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/post_reactions_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/post_reactions_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/post_reactions_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/post_reactions_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/system_config_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/system_config_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/system_config_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/channel_moderation/system_config_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/cluster_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/cluster_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/cluster_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/cluster_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/compliance/compliance_export_multiple_post_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/compliance/compliance_export_multiple_post_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/compliance/compliance_export_multiple_post_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/compliance/compliance_export_multiple_post_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/compliance/compliance_export_ui_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/compliance/compliance_export_ui_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/compliance/compliance_export_ui_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/compliance/compliance_export_ui_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/compliance/data_retention_policies_2_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/compliance/data_retention_policies_2_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/compliance/data_retention_policies_2_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/compliance/data_retention_policies_2_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/compliance/data_retention_policies_3_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/compliance/data_retention_policies_3_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/compliance/data_retention_policies_3_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/compliance/data_retention_policies_3_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/compliance/data_retention_policies_4_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/compliance/data_retention_policies_4_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/compliance/data_retention_policies_4_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/compliance/data_retention_policies_4_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/compliance/data_retention_policies_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/compliance/data_retention_policies_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/compliance/data_retention_policies_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/compliance/data_retention_policies_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/compliance/download_bot_compliance_export_file_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/compliance/download_bot_compliance_export_file_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/compliance/download_bot_compliance_export_file_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/compliance/download_bot_compliance_export_file_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/compliance/download_compliance_export_file_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/compliance/download_compliance_export_file_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/compliance/download_compliance_export_file_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/compliance/download_compliance_export_file_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/compliance/helpers.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/compliance/helpers.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/compliance/helpers.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/compliance/helpers.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/compliance/s3_bucket_storage_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/compliance/s3_bucket_storage_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/compliance/s3_bucket_storage_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/compliance/s3_bucket_storage_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/edition_and_license_link_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/edition_and_license_link_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/edition_and_license_link_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/edition_and_license_link_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/environment_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/environment_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/environment_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/environment_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/group_configuration_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/group_configuration_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/group_configuration_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/group_configuration_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/helpers.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/helpers.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/helpers.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/helpers.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/limited_console_access_not_cloud_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/limited_console_access_not_cloud_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/limited_console_access_not_cloud_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/limited_console_access_not_cloud_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/limited_console_access_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/limited_console_access_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/limited_console_access_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/limited_console_access_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/main_menu_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/main_menu_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/main_menu_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/main_menu_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/openid/openid_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/openid/openid_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/openid/openid_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/openid/openid_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/reporting/site_statistics_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/reporting/site_statistics_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/reporting/site_statistics_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/reporting/site_statistics_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/search_box_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/search_box_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/search_box_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/search_box_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/settings_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/settings_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/settings_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/settings_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/sidebar_link_navigation_cloud_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/sidebar_link_navigation_cloud_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/sidebar_link_navigation_cloud_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/sidebar_link_navigation_cloud_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/sidebar_link_navigation_e20_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/sidebar_link_navigation_e20_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/sidebar_link_navigation_e20_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/sidebar_link_navigation_e20_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/support_packet_generation_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/support_packet_generation_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/support_packet_generation_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/support_packet_generation_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/system_scheme_permission_part2_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/system_scheme_permission_part2_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/system_scheme_permission_part2_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/system_scheme_permission_part2_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/system_scheme_permission_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/system_scheme_permission_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/system_scheme_permission_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/system_scheme_permission_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/team_guest_channel_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/team_guest_channel_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/team_guest_channel_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/team_guest_channel_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/team_members_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/team_members_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/team_members_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/team_members_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/team_scheme_permission_part2_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/team_scheme_permission_part2_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/team_scheme_permission_part2_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/team_scheme_permission_part2_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/team_scheme_permission_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/team_scheme_permission_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/team_scheme_permission_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/team_scheme_permission_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/system_console/ui_and_api/notifications_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/system_console/ui_and_api/notifications_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/system_console/ui_and_api/notifications_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/system_console/ui_and_api/notifications_spec.js diff --git a/e2e/cypress/tests/integration/channels/enterprise/teams/search_teams_spec.js b/e2e-tests/cypress/tests/integration/channels/enterprise/teams/search_teams_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/enterprise/teams/search_teams_spec.js rename to e2e-tests/cypress/tests/integration/channels/enterprise/teams/search_teams_spec.js diff --git a/e2e/cypress/tests/integration/channels/files_and_attachments/cancel_file_upload_spec.js b/e2e-tests/cypress/tests/integration/channels/files_and_attachments/cancel_file_upload_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/files_and_attachments/cancel_file_upload_spec.js rename to e2e-tests/cypress/tests/integration/channels/files_and_attachments/cancel_file_upload_spec.js diff --git a/e2e/cypress/tests/integration/channels/files_and_attachments/channel_files_spec.js b/e2e-tests/cypress/tests/integration/channels/files_and_attachments/channel_files_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/files_and_attachments/channel_files_spec.js rename to e2e-tests/cypress/tests/integration/channels/files_and_attachments/channel_files_spec.js diff --git a/e2e/cypress/tests/integration/channels/files_and_attachments/cloud_upload_files_spec.js b/e2e-tests/cypress/tests/integration/channels/files_and_attachments/cloud_upload_files_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/files_and_attachments/cloud_upload_files_spec.js rename to e2e-tests/cypress/tests/integration/channels/files_and_attachments/cloud_upload_files_spec.js diff --git a/e2e/cypress/tests/integration/channels/files_and_attachments/disabled_file_upload_spec.js b/e2e-tests/cypress/tests/integration/channels/files_and_attachments/disabled_file_upload_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/files_and_attachments/disabled_file_upload_spec.js rename to e2e-tests/cypress/tests/integration/channels/files_and_attachments/disabled_file_upload_spec.js diff --git a/e2e/cypress/tests/integration/channels/files_and_attachments/edit_message_with_attachment_spec.js b/e2e-tests/cypress/tests/integration/channels/files_and_attachments/edit_message_with_attachment_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/files_and_attachments/edit_message_with_attachment_spec.js rename to e2e-tests/cypress/tests/integration/channels/files_and_attachments/edit_message_with_attachment_spec.js diff --git a/e2e/cypress/tests/integration/channels/files_and_attachments/file_preview_audio_spec.js b/e2e-tests/cypress/tests/integration/channels/files_and_attachments/file_preview_audio_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/files_and_attachments/file_preview_audio_spec.js rename to e2e-tests/cypress/tests/integration/channels/files_and_attachments/file_preview_audio_spec.js diff --git a/e2e/cypress/tests/integration/channels/files_and_attachments/file_preview_generic_spec.js b/e2e-tests/cypress/tests/integration/channels/files_and_attachments/file_preview_generic_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/files_and_attachments/file_preview_generic_spec.js rename to e2e-tests/cypress/tests/integration/channels/files_and_attachments/file_preview_generic_spec.js diff --git a/e2e/cypress/tests/integration/channels/files_and_attachments/file_preview_image_spec.js b/e2e-tests/cypress/tests/integration/channels/files_and_attachments/file_preview_image_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/files_and_attachments/file_preview_image_spec.js rename to e2e-tests/cypress/tests/integration/channels/files_and_attachments/file_preview_image_spec.js diff --git a/e2e/cypress/tests/integration/channels/files_and_attachments/file_preview_video_spec.js b/e2e-tests/cypress/tests/integration/channels/files_and_attachments/file_preview_video_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/files_and_attachments/file_preview_video_spec.js rename to e2e-tests/cypress/tests/integration/channels/files_and_attachments/file_preview_video_spec.js diff --git a/e2e/cypress/tests/integration/channels/files_and_attachments/helpers.js b/e2e-tests/cypress/tests/integration/channels/files_and_attachments/helpers.js similarity index 100% rename from e2e/cypress/tests/integration/channels/files_and_attachments/helpers.js rename to e2e-tests/cypress/tests/integration/channels/files_and_attachments/helpers.js diff --git a/e2e/cypress/tests/integration/channels/files_and_attachments/image_link_preview_1_spec.js b/e2e-tests/cypress/tests/integration/channels/files_and_attachments/image_link_preview_1_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/files_and_attachments/image_link_preview_1_spec.js rename to e2e-tests/cypress/tests/integration/channels/files_and_attachments/image_link_preview_1_spec.js diff --git a/e2e/cypress/tests/integration/channels/files_and_attachments/image_link_preview_new_window_spec.js b/e2e-tests/cypress/tests/integration/channels/files_and_attachments/image_link_preview_new_window_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/files_and_attachments/image_link_preview_new_window_spec.js rename to e2e-tests/cypress/tests/integration/channels/files_and_attachments/image_link_preview_new_window_spec.js diff --git a/e2e/cypress/tests/integration/channels/files_and_attachments/image_link_preview_spec.js b/e2e-tests/cypress/tests/integration/channels/files_and_attachments/image_link_preview_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/files_and_attachments/image_link_preview_spec.js rename to e2e-tests/cypress/tests/integration/channels/files_and_attachments/image_link_preview_spec.js diff --git a/e2e/cypress/tests/integration/channels/files_and_attachments/paste_image_spec.js b/e2e-tests/cypress/tests/integration/channels/files_and_attachments/paste_image_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/files_and_attachments/paste_image_spec.js rename to e2e-tests/cypress/tests/integration/channels/files_and_attachments/paste_image_spec.js diff --git a/e2e/cypress/tests/integration/channels/files_and_attachments/upload_files_not_cloud_spec.js b/e2e-tests/cypress/tests/integration/channels/files_and_attachments/upload_files_not_cloud_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/files_and_attachments/upload_files_not_cloud_spec.js rename to e2e-tests/cypress/tests/integration/channels/files_and_attachments/upload_files_not_cloud_spec.js diff --git a/e2e/cypress/tests/integration/channels/files_and_attachments/upload_files_spec.js b/e2e-tests/cypress/tests/integration/channels/files_and_attachments/upload_files_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/files_and_attachments/upload_files_spec.js rename to e2e-tests/cypress/tests/integration/channels/files_and_attachments/upload_files_spec.js diff --git a/e2e/cypress/tests/integration/channels/files_and_attachments/youtube_video_spec.js b/e2e-tests/cypress/tests/integration/channels/files_and_attachments/youtube_video_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/files_and_attachments/youtube_video_spec.js rename to e2e-tests/cypress/tests/integration/channels/files_and_attachments/youtube_video_spec.js diff --git a/e2e/cypress/tests/integration/channels/insights/last_viewed_spec.js b/e2e-tests/cypress/tests/integration/channels/insights/last_viewed_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/insights/last_viewed_spec.js rename to e2e-tests/cypress/tests/integration/channels/insights/last_viewed_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/builtin_commands/common_commands_1_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/builtin_commands/common_commands_1_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/builtin_commands/common_commands_1_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/builtin_commands/common_commands_1_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/builtin_commands/common_commands_2_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/builtin_commands/common_commands_2_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/builtin_commands/common_commands_2_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/builtin_commands/common_commands_2_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/builtin_commands/common_commands_3_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/builtin_commands/common_commands_3_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/builtin_commands/common_commands_3_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/builtin_commands/common_commands_3_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/builtin_commands/groupmsg_command_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/builtin_commands/groupmsg_command_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/builtin_commands/groupmsg_command_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/builtin_commands/groupmsg_command_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/builtin_commands/helper.js b/e2e-tests/cypress/tests/integration/channels/integrations/builtin_commands/helper.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/builtin_commands/helper.js rename to e2e-tests/cypress/tests/integration/channels/integrations/builtin_commands/helper.js diff --git a/e2e/cypress/tests/integration/channels/integrations/builtin_commands/invalid_commands_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/builtin_commands/invalid_commands_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/builtin_commands/invalid_commands_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/builtin_commands/invalid_commands_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/builtin_commands/invite_command_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/builtin_commands/invite_command_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/builtin_commands/invite_command_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/builtin_commands/invite_command_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/builtin_commands/invite_people_command_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/builtin_commands/invite_people_command_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/builtin_commands/invite_people_command_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/builtin_commands/invite_people_command_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/builtin_commands/user_status_commands_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/builtin_commands/user_status_commands_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/builtin_commands/user_status_commands_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/builtin_commands/user_status_commands_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/builtin_commands/user_status_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/builtin_commands/user_status_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/builtin_commands/user_status_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/builtin_commands/user_status_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/custom_slash_commands/custom_slash_commands_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/custom_slash_commands/custom_slash_commands_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/custom_slash_commands/custom_slash_commands_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/custom_slash_commands/custom_slash_commands_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/custom_slash_commands/helpers.js b/e2e-tests/cypress/tests/integration/channels/integrations/custom_slash_commands/helpers.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/custom_slash_commands/helpers.js rename to e2e-tests/cypress/tests/integration/channels/integrations/custom_slash_commands/helpers.js diff --git a/e2e/cypress/tests/integration/channels/integrations/custom_slash_commands/slash_commands_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/custom_slash_commands/slash_commands_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/custom_slash_commands/slash_commands_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/custom_slash_commands/slash_commands_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/incoming_webhook/attachment_does_not_collapse_spec.ts b/e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/attachment_does_not_collapse_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/incoming_webhook/attachment_does_not_collapse_spec.ts rename to e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/attachment_does_not_collapse_spec.ts diff --git a/e2e/cypress/tests/integration/channels/integrations/incoming_webhook/basic_formatting_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/basic_formatting_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/incoming_webhook/basic_formatting_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/basic_formatting_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/incoming_webhook/cancel_out_of_edit_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/cancel_out_of_edit_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/incoming_webhook/cancel_out_of_edit_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/cancel_out_of_edit_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/incoming_webhook/copy_icon_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/copy_icon_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/incoming_webhook/copy_icon_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/copy_icon_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/incoming_webhook/delete_incoming_webhook_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/delete_incoming_webhook_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/incoming_webhook/delete_incoming_webhook_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/delete_incoming_webhook_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/incoming_webhook/description_length_check_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/description_length_check_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/incoming_webhook/description_length_check_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/description_length_check_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/incoming_webhook/disallow_username_profile_override_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/disallow_username_profile_override_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/incoming_webhook/disallow_username_profile_override_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/disallow_username_profile_override_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/incoming_webhook/edit_incoming_webhook_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/edit_incoming_webhook_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/incoming_webhook/edit_incoming_webhook_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/edit_incoming_webhook_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/incoming_webhook/helpers.js b/e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/helpers.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/incoming_webhook/helpers.js rename to e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/helpers.js diff --git a/e2e/cypress/tests/integration/channels/integrations/incoming_webhook/inapp_username_profile_override_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/inapp_username_profile_override_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/incoming_webhook/inapp_username_profile_override_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/inapp_username_profile_override_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/incoming_webhook/incoming_webhook_creates_dm_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/incoming_webhook_creates_dm_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/incoming_webhook/incoming_webhook_creates_dm_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/incoming_webhook_creates_dm_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/incoming_webhook/incoming_webhook_is_image_only_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/incoming_webhook_is_image_only_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/incoming_webhook/incoming_webhook_is_image_only_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/incoming_webhook_is_image_only_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/incoming_webhook/integrations_display_on_team_where_created_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/integrations_display_on_team_where_created_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/incoming_webhook/integrations_display_on_team_where_created_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/integrations_display_on_team_where_created_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/incoming_webhook/invalid_attachment_URL_webhook_spec.ts b/e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/invalid_attachment_URL_webhook_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/incoming_webhook/invalid_attachment_URL_webhook_spec.ts rename to e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/invalid_attachment_URL_webhook_spec.ts diff --git a/e2e/cypress/tests/integration/channels/integrations/incoming_webhook/long_url_embedded_image_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/long_url_embedded_image_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/incoming_webhook/long_url_embedded_image_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/long_url_embedded_image_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/incoming_webhook/setting_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/setting_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/incoming_webhook/setting_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/setting_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/incoming_webhook/setup_incoming_webhook_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/setup_incoming_webhook_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/incoming_webhook/setup_incoming_webhook_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/setup_incoming_webhook_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/incoming_webhook/slack_formatting_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/slack_formatting_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/incoming_webhook/slack_formatting_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/slack_formatting_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/incoming_webhook/webhook_posts_when_creator_not_in_channel_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/webhook_posts_when_creator_not_in_channel_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/incoming_webhook/webhook_posts_when_creator_not_in_channel_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/incoming_webhook/webhook_posts_when_creator_not_in_channel_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/integrations_page_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/integrations_page_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/integrations_page_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/integrations_page_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/integrations_search_gives_feedback_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/integrations_search_gives_feedback_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/integrations_search_gives_feedback_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/integrations_search_gives_feedback_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/integrations_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/integrations_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/integrations_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/integrations_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/message_to_channel_via_slash_command_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/message_to_channel_via_slash_command_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/message_to_channel_via_slash_command_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/message_to_channel_via_slash_command_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/outgoing_webhook/delete_outgoing_webhook_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/outgoing_webhook/delete_outgoing_webhook_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/outgoing_webhook/delete_outgoing_webhook_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/outgoing_webhook/delete_outgoing_webhook_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/outgoing_webhook/disable_outgoing_webhook_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/outgoing_webhook/disable_outgoing_webhook_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/outgoing_webhook/disable_outgoing_webhook_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/outgoing_webhook/disable_outgoing_webhook_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/outgoing_webhook/disable_override_username_profile_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/outgoing_webhook/disable_override_username_profile_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/outgoing_webhook/disable_override_username_profile_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/outgoing_webhook/disable_override_username_profile_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/outgoing_webhook/prompt_set_status_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/outgoing_webhook/prompt_set_status_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/outgoing_webhook/prompt_set_status_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/outgoing_webhook/prompt_set_status_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/outgoing_webhook/regenerate_token_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/outgoing_webhook/regenerate_token_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/outgoing_webhook/regenerate_token_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/outgoing_webhook/regenerate_token_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/outgoing_webhook/search_on_outgoing_webhooks_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/outgoing_webhook/search_on_outgoing_webhooks_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/outgoing_webhook/search_on_outgoing_webhooks_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/outgoing_webhook/search_on_outgoing_webhooks_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/outgoing_webhook/token_copy_icon_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/outgoing_webhook/token_copy_icon_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/outgoing_webhook/token_copy_icon_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/outgoing_webhook/token_copy_icon_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/plugin_slash_command_stays_visible_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/plugin_slash_command_stays_visible_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/plugin_slash_command_stays_visible_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/plugin_slash_command_stays_visible_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/poll_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/poll_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/poll_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/poll_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/regen_token_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/regen_token_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/regen_token_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/regen_token_spec.js diff --git a/e2e/cypress/tests/integration/channels/integrations/slash_commands_spec.js b/e2e-tests/cypress/tests/integration/channels/integrations/slash_commands_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/integrations/slash_commands_spec.js rename to e2e-tests/cypress/tests/integration/channels/integrations/slash_commands_spec.js diff --git a/e2e/cypress/tests/integration/channels/interactive_dialog/boolean_spec.js b/e2e-tests/cypress/tests/integration/channels/interactive_dialog/boolean_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/interactive_dialog/boolean_spec.js rename to e2e-tests/cypress/tests/integration/channels/interactive_dialog/boolean_spec.js diff --git a/e2e/cypress/tests/integration/channels/interactive_dialog/demo_boolean_spec.ts b/e2e-tests/cypress/tests/integration/channels/interactive_dialog/demo_boolean_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/interactive_dialog/demo_boolean_spec.ts rename to e2e-tests/cypress/tests/integration/channels/interactive_dialog/demo_boolean_spec.ts diff --git a/e2e/cypress/tests/integration/channels/interactive_dialog/full_dialog_spec.js b/e2e-tests/cypress/tests/integration/channels/interactive_dialog/full_dialog_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/interactive_dialog/full_dialog_spec.js rename to e2e-tests/cypress/tests/integration/channels/interactive_dialog/full_dialog_spec.js diff --git a/e2e/cypress/tests/integration/channels/interactive_dialog/scrollable_spec.js b/e2e-tests/cypress/tests/integration/channels/interactive_dialog/scrollable_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/interactive_dialog/scrollable_spec.js rename to e2e-tests/cypress/tests/integration/channels/interactive_dialog/scrollable_spec.js diff --git a/e2e/cypress/tests/integration/channels/interactive_dialog/simple_dialog_spec.js b/e2e-tests/cypress/tests/integration/channels/interactive_dialog/simple_dialog_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/interactive_dialog/simple_dialog_spec.js rename to e2e-tests/cypress/tests/integration/channels/interactive_dialog/simple_dialog_spec.js diff --git a/e2e/cypress/tests/integration/channels/interactive_menu/basic_options_spec.js b/e2e-tests/cypress/tests/integration/channels/interactive_menu/basic_options_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/interactive_menu/basic_options_spec.js rename to e2e-tests/cypress/tests/integration/channels/interactive_menu/basic_options_spec.js diff --git a/e2e/cypress/tests/integration/channels/interactive_menu/select_with_keys_spec.js b/e2e-tests/cypress/tests/integration/channels/interactive_menu/select_with_keys_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/interactive_menu/select_with_keys_spec.js rename to e2e-tests/cypress/tests/integration/channels/interactive_menu/select_with_keys_spec.js diff --git a/e2e/cypress/tests/integration/channels/interactive_menu/slack_parsing_message_button_spec.js b/e2e-tests/cypress/tests/integration/channels/interactive_menu/slack_parsing_message_button_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/interactive_menu/slack_parsing_message_button_spec.js rename to e2e-tests/cypress/tests/integration/channels/interactive_menu/slack_parsing_message_button_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/alt_option_plus_up_down_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/alt_option_plus_up_down_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/alt_option_plus_up_down_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/alt_option_plus_up_down_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/backspace_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/backspace_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/backspace_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/backspace_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_alt_I_toggles_channel_info_rhs_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_alt_I_toggles_channel_info_rhs_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_alt_I_toggles_channel_info_rhs_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_alt_I_toggles_channel_info_rhs_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_at_username_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_at_username_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_at_username_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_at_username_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_channel_switch_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_channel_switch_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_channel_switch_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_channel_switch_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_focuses_message_box_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_focuses_message_box_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_focuses_message_box_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_focuses_message_box_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_open_channel_from_global_threads_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_open_channel_from_global_threads_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_open_channel_from_global_threads_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_open_channel_from_global_threads_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_open_gm_with_mouse_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_open_gm_with_mouse_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_open_gm_with_mouse_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_open_gm_with_mouse_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_unreads_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_unreads_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_unreads_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_unreads_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_user_from_other_team_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_user_from_other_team_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_user_from_other_team_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_k_user_from_other_team_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_l_set_message_focus_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_l_set_message_focus_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_l_set_message_focus_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_l_set_message_focus_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_a_account_settings_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_a_account_settings_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_a_account_settings_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_a_account_settings_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_l_does_not_change_focus_to_msgbox_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_l_does_not_change_focus_to_msgbox_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_l_does_not_change_focus_to_msgbox_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_l_does_not_change_focus_to_msgbox_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_m_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_m_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_m_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_m_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_slash/helpers.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_slash/helpers.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_slash/helpers.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_slash/helpers.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_slash/not_open_emoji_picker_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_slash/not_open_emoji_picker_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_slash/not_open_emoji_picker_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_slash/not_open_emoji_picker_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_slash/react_to_center_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_slash/react_to_center_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_slash/react_to_center_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_slash/react_to_center_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_slash/react_to_rhs_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_slash/react_to_rhs_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_slash/react_to_rhs_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_shift_slash/react_to_rhs_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_up_down_in_rhs_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_up_down_in_rhs_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_up_down_in_rhs_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_up_down_in_rhs_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_up_down_no_action_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_up_down_no_action_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_up_down_no_action_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/ctrl_cmd_up_down_no_action_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/dot_menu_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/dot_menu_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/dot_menu_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/dot_menu_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/esc_close_modal_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/esc_close_modal_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/esc_close_modal_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/esc_close_modal_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/keyboard_shortcuts_1_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/keyboard_shortcuts_1_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/keyboard_shortcuts_1_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/keyboard_shortcuts_1_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/keyboard_shortcuts_2_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/keyboard_shortcuts_2_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/keyboard_shortcuts_2_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/keyboard_shortcuts_2_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/keyboard_shortcuts_3_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/keyboard_shortcuts_3_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/keyboard_shortcuts_3_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/keyboard_shortcuts_3_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/shift_up_focuses_on_rhs_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/shift_up_focuses_on_rhs_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/shift_up_focuses_on_rhs_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/shift_up_focuses_on_rhs_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/system_message_not_open_for_edit_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/system_message_not_open_for_edit_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/system_message_not_open_for_edit_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/system_message_not_open_for_edit_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/up_arrow_edit_message_rhs_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/up_arrow_edit_message_rhs_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/up_arrow_edit_message_rhs_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/up_arrow_edit_message_rhs_spec.js diff --git a/e2e/cypress/tests/integration/channels/keyboard_shortcuts/up_arrow_edit_message_spec.js b/e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/up_arrow_edit_message_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/keyboard_shortcuts/up_arrow_edit_message_spec.js rename to e2e-tests/cypress/tests/integration/channels/keyboard_shortcuts/up_arrow_edit_message_spec.js diff --git a/e2e/cypress/tests/integration/channels/large_data_sets/unreads_channels_spec.ts b/e2e-tests/cypress/tests/integration/channels/large_data_sets/unreads_channels_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/large_data_sets/unreads_channels_spec.ts rename to e2e-tests/cypress/tests/integration/channels/large_data_sets/unreads_channels_spec.ts diff --git a/e2e/cypress/tests/integration/channels/mark_as_unread/archive_channel_mark_as_unread_spec.js b/e2e-tests/cypress/tests/integration/channels/mark_as_unread/archive_channel_mark_as_unread_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/mark_as_unread/archive_channel_mark_as_unread_spec.js rename to e2e-tests/cypress/tests/integration/channels/mark_as_unread/archive_channel_mark_as_unread_spec.js diff --git a/e2e/cypress/tests/integration/channels/mark_as_unread/bot_post_mark_as_unread_spec.js b/e2e-tests/cypress/tests/integration/channels/mark_as_unread/bot_post_mark_as_unread_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/mark_as_unread/bot_post_mark_as_unread_spec.js rename to e2e-tests/cypress/tests/integration/channels/mark_as_unread/bot_post_mark_as_unread_spec.js diff --git a/e2e/cypress/tests/integration/channels/mark_as_unread/channel_unread_spec.js b/e2e-tests/cypress/tests/integration/channels/mark_as_unread/channel_unread_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/mark_as_unread/channel_unread_spec.js rename to e2e-tests/cypress/tests/integration/channels/mark_as_unread/channel_unread_spec.js diff --git a/e2e/cypress/tests/integration/channels/mark_as_unread/helpers.js b/e2e-tests/cypress/tests/integration/channels/mark_as_unread/helpers.js similarity index 100% rename from e2e/cypress/tests/integration/channels/mark_as_unread/helpers.js rename to e2e-tests/cypress/tests/integration/channels/mark_as_unread/helpers.js diff --git a/e2e/cypress/tests/integration/channels/mark_as_unread/leave_channel_unread_spec.js b/e2e-tests/cypress/tests/integration/channels/mark_as_unread/leave_channel_unread_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/mark_as_unread/leave_channel_unread_spec.js rename to e2e-tests/cypress/tests/integration/channels/mark_as_unread/leave_channel_unread_spec.js diff --git a/e2e/cypress/tests/integration/channels/mark_as_unread/mark_as_unread_spec.js b/e2e-tests/cypress/tests/integration/channels/mark_as_unread/mark_as_unread_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/mark_as_unread/mark_as_unread_spec.js rename to e2e-tests/cypress/tests/integration/channels/mark_as_unread/mark_as_unread_spec.js diff --git a/e2e/cypress/tests/integration/channels/mark_as_unread/mark_as_unread_using_shortcuts_spec.js b/e2e-tests/cypress/tests/integration/channels/mark_as_unread/mark_as_unread_using_shortcuts_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/mark_as_unread/mark_as_unread_using_shortcuts_spec.js rename to e2e-tests/cypress/tests/integration/channels/mark_as_unread/mark_as_unread_using_shortcuts_spec.js diff --git a/e2e/cypress/tests/integration/channels/mark_as_unread/mark_dm_post_as_unread_spec.js b/e2e-tests/cypress/tests/integration/channels/mark_as_unread/mark_dm_post_as_unread_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/mark_as_unread/mark_dm_post_as_unread_spec.js rename to e2e-tests/cypress/tests/integration/channels/mark_as_unread/mark_dm_post_as_unread_spec.js diff --git a/e2e/cypress/tests/integration/channels/mark_as_unread/mark_gm_as_unread_spec.js b/e2e-tests/cypress/tests/integration/channels/mark_as_unread/mark_gm_as_unread_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/mark_as_unread/mark_gm_as_unread_spec.js rename to e2e-tests/cypress/tests/integration/channels/mark_as_unread/mark_gm_as_unread_spec.js diff --git a/e2e/cypress/tests/integration/channels/mark_as_unread/mark_mentions_as_unread_spec.js b/e2e-tests/cypress/tests/integration/channels/mark_as_unread/mark_mentions_as_unread_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/mark_as_unread/mark_mentions_as_unread_spec.js rename to e2e-tests/cypress/tests/integration/channels/mark_as_unread/mark_mentions_as_unread_spec.js diff --git a/e2e/cypress/tests/integration/channels/mark_as_unread/toast_appears_unread_spec.js b/e2e-tests/cypress/tests/integration/channels/mark_as_unread/toast_appears_unread_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/mark_as_unread/toast_appears_unread_spec.js rename to e2e-tests/cypress/tests/integration/channels/mark_as_unread/toast_appears_unread_spec.js diff --git a/e2e/cypress/tests/integration/channels/mark_as_unread/unread_toast_count_spec.js b/e2e-tests/cypress/tests/integration/channels/mark_as_unread/unread_toast_count_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/mark_as_unread/unread_toast_count_spec.js rename to e2e-tests/cypress/tests/integration/channels/mark_as_unread/unread_toast_count_spec.js diff --git a/e2e/cypress/tests/integration/channels/markdown/markdown_image_spec.js b/e2e-tests/cypress/tests/integration/channels/markdown/markdown_image_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/markdown/markdown_image_spec.js rename to e2e-tests/cypress/tests/integration/channels/markdown/markdown_image_spec.js diff --git a/e2e/cypress/tests/integration/channels/markdown/markdown_text_spec.js b/e2e-tests/cypress/tests/integration/channels/markdown/markdown_text_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/markdown/markdown_text_spec.js rename to e2e-tests/cypress/tests/integration/channels/markdown/markdown_text_spec.js diff --git a/e2e/cypress/tests/integration/channels/menus/main_menu_spec.js b/e2e-tests/cypress/tests/integration/channels/menus/main_menu_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/menus/main_menu_spec.js rename to e2e-tests/cypress/tests/integration/channels/menus/main_menu_spec.js diff --git a/e2e/cypress/tests/integration/channels/menus/status_dropdown_spec.js b/e2e-tests/cypress/tests/integration/channels/menus/status_dropdown_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/menus/status_dropdown_spec.js rename to e2e-tests/cypress/tests/integration/channels/menus/status_dropdown_spec.js diff --git a/e2e/cypress/tests/integration/channels/message_forwarding/forward_message_from_dm_spec.js b/e2e-tests/cypress/tests/integration/channels/message_forwarding/forward_message_from_dm_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/message_forwarding/forward_message_from_dm_spec.js rename to e2e-tests/cypress/tests/integration/channels/message_forwarding/forward_message_from_dm_spec.js diff --git a/e2e/cypress/tests/integration/channels/message_forwarding/forward_message_from_gm_spec.js b/e2e-tests/cypress/tests/integration/channels/message_forwarding/forward_message_from_gm_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/message_forwarding/forward_message_from_gm_spec.js rename to e2e-tests/cypress/tests/integration/channels/message_forwarding/forward_message_from_gm_spec.js diff --git a/e2e/cypress/tests/integration/channels/message_forwarding/forward_message_from_private_channel_spec.js b/e2e-tests/cypress/tests/integration/channels/message_forwarding/forward_message_from_private_channel_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/message_forwarding/forward_message_from_private_channel_spec.js rename to e2e-tests/cypress/tests/integration/channels/message_forwarding/forward_message_from_private_channel_spec.js diff --git a/e2e/cypress/tests/integration/channels/message_forwarding/forward_message_from_public_channel_spec.js b/e2e-tests/cypress/tests/integration/channels/message_forwarding/forward_message_from_public_channel_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/message_forwarding/forward_message_from_public_channel_spec.js rename to e2e-tests/cypress/tests/integration/channels/message_forwarding/forward_message_from_public_channel_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/at_mentions_user_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/at_mentions_user_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/at_mentions_user_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/at_mentions_user_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/autocomplete_shown_each_channel_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/autocomplete_shown_each_channel_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/autocomplete_shown_each_channel_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/autocomplete_shown_each_channel_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/autocomplete_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/autocomplete_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/autocomplete_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/autocomplete_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/autocomplete_with_space_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/autocomplete_with_space_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/autocomplete_with_space_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/autocomplete_with_space_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/center_channel_rhs_overlap_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/center_channel_rhs_overlap_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/center_channel_rhs_overlap_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/center_channel_rhs_overlap_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/channel_and_posts_links_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/channel_and_posts_links_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/channel_and_posts_links_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/channel_and_posts_links_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/channel_menu_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/channel_menu_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/channel_menu_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/channel_menu_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/channel_read_after_permalink_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/channel_read_after_permalink_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/channel_read_after_permalink_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/channel_read_after_permalink_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/channel_users_interactions_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/channel_users_interactions_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/channel_users_interactions_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/channel_users_interactions_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/collapse_link_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/collapse_link_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/collapse_link_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/collapse_link_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/collapsed_message_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/collapsed_message_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/collapsed_message_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/collapsed_message_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/copy_post_text_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/copy_post_text_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/copy_post_text_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/copy_post_text_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/ctrl_cmd_k_find_gm_by_matching_name_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/ctrl_cmd_k_find_gm_by_matching_name_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/ctrl_cmd_k_find_gm_by_matching_name_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/ctrl_cmd_k_find_gm_by_matching_name_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/ctrl_cmd_k_open_dm_with_mouse_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/ctrl_cmd_k_open_dm_with_mouse_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/ctrl_cmd_k_open_dm_with_mouse_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/ctrl_cmd_k_open_dm_with_mouse_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/date_separator_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/date_separator_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/date_separator_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/date_separator_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/direct_message_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/direct_message_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/direct_message_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/direct_message_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/dm_list_of_users_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/dm_list_of_users_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/dm_list_of_users_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/dm_list_of_users_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/draft_with_only_2_byte_characters_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/draft_with_only_2_byte_characters_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/draft_with_only_2_byte_characters_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/draft_with_only_2_byte_characters_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/edit_message_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/edit_message_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/edit_message_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/edit_message_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/emoji_followed_by_punctuation_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/emoji_followed_by_punctuation_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/emoji_followed_by_punctuation_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/emoji_followed_by_punctuation_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/emoji_gender_spec.ts b/e2e-tests/cypress/tests/integration/channels/messaging/emoji_gender_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/emoji_gender_spec.ts rename to e2e-tests/cypress/tests/integration/channels/messaging/emoji_gender_spec.ts diff --git a/e2e/cypress/tests/integration/channels/messaging/emoji_insert_position_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/emoji_insert_position_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/emoji_insert_position_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/emoji_insert_position_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/emoji_keyboard_entry_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/emoji_keyboard_entry_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/emoji_keyboard_entry_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/emoji_keyboard_entry_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/emoji_no_overlap_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/emoji_no_overlap_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/emoji_no_overlap_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/emoji_no_overlap_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/emoji_picker_keyboard_usability_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/emoji_picker_keyboard_usability_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/emoji_picker_keyboard_usability_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/emoji_picker_keyboard_usability_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/emoji_recently_used_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/emoji_recently_used_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/emoji_recently_used_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/emoji_recently_used_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/emoji_size_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/emoji_size_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/emoji_size_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/emoji_size_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/emoji_skin_tone_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/emoji_skin_tone_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/emoji_skin_tone_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/emoji_skin_tone_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/emoji_to_markdown_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/emoji_to_markdown_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/emoji_to_markdown_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/emoji_to_markdown_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/file_upload_in_center_channel_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/file_upload_in_center_channel_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/file_upload_in_center_channel_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/file_upload_in_center_channel_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/focus_move_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/focus_move_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/focus_move_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/focus_move_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/group_message_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/group_message_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/group_message_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/group_message_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/header_not_cloud_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/header_not_cloud_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/header_not_cloud_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/header_not_cloud_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/header_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/header_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/header_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/header_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/helpers.js b/e2e-tests/cypress/tests/integration/channels/messaging/helpers.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/helpers.js rename to e2e-tests/cypress/tests/integration/channels/messaging/helpers.js diff --git a/e2e/cypress/tests/integration/channels/messaging/image_attachment_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/image_attachment_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/image_attachment_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/image_attachment_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/inline_images_open_preview_window_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/inline_images_open_preview_window_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/inline_images_open_preview_window_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/inline_images_open_preview_window_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/inline_markdown_image_link_open_link_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/inline_markdown_image_link_open_link_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/inline_markdown_image_link_open_link_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/inline_markdown_image_link_open_link_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/input_box_expands_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/input_box_expands_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/input_box_expands_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/input_box_expands_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/input_box_expands_with_rhs_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/input_box_expands_with_rhs_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/input_box_expands_with_rhs_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/input_box_expands_with_rhs_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/invalid_emojis_as_text_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/invalid_emojis_as_text_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/invalid_emojis_as_text_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/invalid_emojis_as_text_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/local_date_time_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/local_date_time_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/local_date_time_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/local_date_time_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/long_draft_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/long_draft_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/long_draft_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/long_draft_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/long_post_attachments_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/long_post_attachments_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/long_post_attachments_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/long_post_attachments_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/markdown_preview_inline_image_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/markdown_preview_inline_image_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/markdown_preview_inline_image_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/markdown_preview_inline_image_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/markdown_quotation_paragraphs_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/markdown_quotation_paragraphs_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/markdown_quotation_paragraphs_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/markdown_quotation_paragraphs_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/markdown_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/markdown_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/markdown_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/markdown_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/mention_autocomplete_overlap_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/mention_autocomplete_overlap_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/mention_autocomplete_overlap_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/mention_autocomplete_overlap_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_auto_response_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_auto_response_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_auto_response_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_auto_response_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_bullets_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_bullets_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_bullets_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_bullets_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_by_aeroplane_icon_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_by_aeroplane_icon_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_by_aeroplane_icon_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_by_aeroplane_icon_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_channel_draw_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_channel_draw_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_channel_draw_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_channel_draw_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_channel_reference_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_channel_reference_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_channel_reference_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_channel_reference_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_deleted_on_reply_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_deleted_on_reply_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_deleted_on_reply_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_deleted_on_reply_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_deletion_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_deletion_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_deletion_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_deletion_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_draft_persistance_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_draft_persistance_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_draft_persistance_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_draft_persistance_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_draft_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_draft_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_draft_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_draft_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_draft_then_switch_channel_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_draft_then_switch_channel_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_draft_then_switch_channel_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_draft_then_switch_channel_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_draft_with_attachment_then_switch_channel_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_draft_with_attachment_then_switch_channel_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_draft_with_attachment_then_switch_channel_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_draft_with_attachment_then_switch_channel_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_edit_post_clear_text_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_edit_post_clear_text_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_edit_post_clear_text_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_edit_post_clear_text_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_edit_post_history_spec.ts b/e2e-tests/cypress/tests/integration/channels/messaging/message_edit_post_history_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_edit_post_history_spec.ts rename to e2e-tests/cypress/tests/integration/channels/messaging/message_edit_post_history_spec.ts diff --git a/e2e/cypress/tests/integration/channels/messaging/message_edit_post_with_attachment_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_edit_post_with_attachment_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_edit_post_with_attachment_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_edit_post_with_attachment_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_emoji_jumbo_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_emoji_jumbo_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_emoji_jumbo_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_emoji_jumbo_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_ephemeral_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_ephemeral_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_ephemeral_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_ephemeral_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_in_another_language_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_in_another_language_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_in_another_language_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_in_another_language_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_parse_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_parse_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_parse_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_parse_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_permalink_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_permalink_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_permalink_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_permalink_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_pinning_unpinning_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_pinning_unpinning_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_pinning_unpinning_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_pinning_unpinning_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_reaction_gm_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_reaction_gm_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_reaction_gm_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_reaction_gm_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_reaction_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_reaction_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_reaction_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_reaction_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_reply_bot_post_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_reply_bot_post_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_reply_bot_post_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_reply_bot_post_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_reply_gm_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_reply_gm_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_reply_gm_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_reply_gm_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_reply_input_box_expand_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_reply_input_box_expand_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_reply_input_box_expand_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_reply_input_box_expand_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_reply_part2_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_reply_part2_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_reply_part2_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_reply_part2_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_reply_scrollable_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_reply_scrollable_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_reply_scrollable_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_reply_scrollable_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_reply_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_reply_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_reply_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_reply_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_reply_too_long_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_reply_too_long_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_reply_too_long_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_reply_too_long_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_shortlinking_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_shortlinking_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_shortlinking_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_shortlinking_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/message_with_gif_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/message_with_gif_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/message_with_gif_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/message_with_gif_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/mobile_message_deletion_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/mobile_message_deletion_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/mobile_message_deletion_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/mobile_message_deletion_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/mobile_profile_popover_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/mobile_profile_popover_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/mobile_profile_popover_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/mobile_profile_popover_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/no_matches_for_autocomplete_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/no_matches_for_autocomplete_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/no_matches_for_autocomplete_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/no_matches_for_autocomplete_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/permalink_click_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/permalink_click_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/permalink_click_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/permalink_click_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/permalink_loading_indicator_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/permalink_loading_indicator_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/permalink_loading_indicator_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/permalink_loading_indicator_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/permalink_message_edit_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/permalink_message_edit_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/permalink_message_edit_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/permalink_message_edit_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/pinned_parent_post_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/pinned_parent_post_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/pinned_parent_post_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/pinned_parent_post_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/pinned_posts_1_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/pinned_posts_1_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/pinned_posts_1_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/pinned_posts_1_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/pinned_posts_2_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/pinned_posts_2_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/pinned_posts_2_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/pinned_posts_2_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/post_header_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/post_header_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/post_header_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/post_header_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/post_html_table_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/post_html_table_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/post_html_table_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/post_html_table_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/post_options_menu_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/post_options_menu_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/post_options_menu_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/post_options_menu_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/post_pre_header_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/post_pre_header_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/post_pre_header_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/post_pre_header_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/post_textbox_height_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/post_textbox_height_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/post_textbox_height_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/post_textbox_height_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/private_channel_open_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/private_channel_open_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/private_channel_open_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/private_channel_open_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/quick_send_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/quick_send_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/quick_send_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/quick_send_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/quote_notation_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/quote_notation_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/quote_notation_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/quote_notation_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/reactions_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/reactions_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/reactions_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/reactions_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/receive_message_on_socket_reconnect_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/receive_message_on_socket_reconnect_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/receive_message_on_socket_reconnect_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/receive_message_on_socket_reconnect_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/remove_gif_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/remove_gif_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/remove_gif_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/remove_gif_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/remove_last_post_in_channel_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/remove_last_post_in_channel_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/remove_last_post_in_channel_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/remove_last_post_in_channel_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/save_post_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/save_post_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/save_post_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/save_post_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/scroll_channel_messages_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/scroll_channel_messages_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/scroll_channel_messages_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/scroll_channel_messages_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/send_message_via_profile_popover_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/send_message_via_profile_popover_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/send_message_via_profile_popover_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/send_message_via_profile_popover_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/single_image_thumbnail_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/single_image_thumbnail_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/single_image_thumbnail_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/single_image_thumbnail_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/strikethrough_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/strikethrough_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/strikethrough_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/strikethrough_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/system_message_limited_options_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/system_message_limited_options_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/system_message_limited_options_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/system_message_limited_options_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/system_message_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/system_message_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/system_message_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/system_message_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/thread_appears_and_scrollable_in_the_rhs_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/thread_appears_and_scrollable_in_the_rhs_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/thread_appears_and_scrollable_in_the_rhs_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/thread_appears_and_scrollable_in_the_rhs_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/tooltip_visual_verification_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/tooltip_visual_verification_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/tooltip_visual_verification_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/tooltip_visual_verification_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/tooltips_on_top_nav_channel_icons_posts_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/tooltips_on_top_nav_channel_icons_posts_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/tooltips_on_top_nav_channel_icons_posts_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/tooltips_on_top_nav_channel_icons_posts_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/typing_on_middle_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/typing_on_middle_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/typing_on_middle_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/typing_on_middle_spec.js diff --git a/e2e/cypress/tests/integration/channels/messaging/typing_should_show_up_when_editing_spec.js b/e2e-tests/cypress/tests/integration/channels/messaging/typing_should_show_up_when_editing_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/messaging/typing_should_show_up_when_editing_spec.js rename to e2e-tests/cypress/tests/integration/channels/messaging/typing_should_show_up_when_editing_spec.js diff --git a/e2e/cypress/tests/integration/channels/modals/quick_switcher_spec.js b/e2e-tests/cypress/tests/integration/channels/modals/quick_switcher_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/modals/quick_switcher_spec.js rename to e2e-tests/cypress/tests/integration/channels/modals/quick_switcher_spec.js diff --git a/e2e/cypress/tests/integration/channels/multi_team_and_dm/channel_user_count_spec.js b/e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/channel_user_count_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/multi_team_and_dm/channel_user_count_spec.js rename to e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/channel_user_count_spec.js diff --git a/e2e/cypress/tests/integration/channels/multi_team_and_dm/check_user_status_spec.js b/e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/check_user_status_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/multi_team_and_dm/check_user_status_spec.js rename to e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/check_user_status_spec.js diff --git a/e2e/cypress/tests/integration/channels/multi_team_and_dm/close_current_dm_redirects_spec.js b/e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/close_current_dm_redirects_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/multi_team_and_dm/close_current_dm_redirects_spec.js rename to e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/close_current_dm_redirects_spec.js diff --git a/e2e/cypress/tests/integration/channels/multi_team_and_dm/close_gm_via_menu_spec.js b/e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/close_gm_via_menu_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/multi_team_and_dm/close_gm_via_menu_spec.js rename to e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/close_gm_via_menu_spec.js diff --git a/e2e/cypress/tests/integration/channels/multi_team_and_dm/dm_more_searching_from_page_spec.js b/e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/dm_more_searching_from_page_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/multi_team_and_dm/dm_more_searching_from_page_spec.js rename to e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/dm_more_searching_from_page_spec.js diff --git a/e2e/cypress/tests/integration/channels/multi_team_and_dm/dm_more_show_user_count_spec.js b/e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/dm_more_show_user_count_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/multi_team_and_dm/dm_more_show_user_count_spec.js rename to e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/dm_more_show_user_count_spec.js diff --git a/e2e/cypress/tests/integration/channels/multi_team_and_dm/existing_channel_name_spec.js b/e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/existing_channel_name_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/multi_team_and_dm/existing_channel_name_spec.js rename to e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/existing_channel_name_spec.js diff --git a/e2e/cypress/tests/integration/channels/multi_team_and_dm/favorite_and_close_spec.js b/e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/favorite_and_close_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/multi_team_and_dm/favorite_and_close_spec.js rename to e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/favorite_and_close_spec.js diff --git a/e2e/cypress/tests/integration/channels/multi_team_and_dm/gm_add_user_spec.js b/e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/gm_add_user_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/multi_team_and_dm/gm_add_user_spec.js rename to e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/gm_add_user_spec.js diff --git a/e2e/cypress/tests/integration/channels/multi_team_and_dm/gm_header_spec.js b/e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/gm_header_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/multi_team_and_dm/gm_header_spec.js rename to e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/gm_header_spec.js diff --git a/e2e/cypress/tests/integration/channels/multi_team_and_dm/join_open_team_from_dm_spec.js b/e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/join_open_team_from_dm_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/multi_team_and_dm/join_open_team_from_dm_spec.js rename to e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/join_open_team_from_dm_spec.js diff --git a/e2e/cypress/tests/integration/channels/multi_team_and_dm/max_gm_members_spec.js b/e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/max_gm_members_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/multi_team_and_dm/max_gm_members_spec.js rename to e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/max_gm_members_spec.js diff --git a/e2e/cypress/tests/integration/channels/multi_team_and_dm/multi_team_join_spec.js b/e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/multi_team_join_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/multi_team_and_dm/multi_team_join_spec.js rename to e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/multi_team_join_spec.js diff --git a/e2e/cypress/tests/integration/channels/multi_team_and_dm/multi_team_spec.js b/e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/multi_team_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/multi_team_and_dm/multi_team_spec.js rename to e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/multi_team_spec.js diff --git a/e2e/cypress/tests/integration/channels/multi_team_and_dm/send_dm_user_no_team_spec.js b/e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/send_dm_user_no_team_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/multi_team_and_dm/send_dm_user_no_team_spec.js rename to e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/send_dm_user_no_team_spec.js diff --git a/e2e/cypress/tests/integration/channels/multi_team_and_dm/system_message_spec.js b/e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/system_message_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/multi_team_and_dm/system_message_spec.js rename to e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/system_message_spec.js diff --git a/e2e/cypress/tests/integration/channels/multi_team_and_dm/town_square_not_marked_as_unread_spec.js b/e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/town_square_not_marked_as_unread_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/multi_team_and_dm/town_square_not_marked_as_unread_spec.js rename to e2e-tests/cypress/tests/integration/channels/multi_team_and_dm/town_square_not_marked_as_unread_spec.js diff --git a/e2e/cypress/tests/integration/channels/notifications/at_icon_still_shows_mentions_list_with_deactivated_triggers_spec.js b/e2e-tests/cypress/tests/integration/channels/notifications/at_icon_still_shows_mentions_list_with_deactivated_triggers_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/notifications/at_icon_still_shows_mentions_list_with_deactivated_triggers_spec.js rename to e2e-tests/cypress/tests/integration/channels/notifications/at_icon_still_shows_mentions_list_with_deactivated_triggers_spec.js diff --git a/e2e/cypress/tests/integration/channels/notifications/at_mentions_spec.js b/e2e-tests/cypress/tests/integration/channels/notifications/at_mentions_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/notifications/at_mentions_spec.js rename to e2e-tests/cypress/tests/integration/channels/notifications/at_mentions_spec.js diff --git a/e2e/cypress/tests/integration/channels/notifications/browser_tab_notification_1_spec.js b/e2e-tests/cypress/tests/integration/channels/notifications/browser_tab_notification_1_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/notifications/browser_tab_notification_1_spec.js rename to e2e-tests/cypress/tests/integration/channels/notifications/browser_tab_notification_1_spec.js diff --git a/e2e/cypress/tests/integration/channels/notifications/browser_tab_notification_2_spec.js b/e2e-tests/cypress/tests/integration/channels/notifications/browser_tab_notification_2_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/notifications/browser_tab_notification_2_spec.js rename to e2e-tests/cypress/tests/integration/channels/notifications/browser_tab_notification_2_spec.js diff --git a/e2e/cypress/tests/integration/channels/notifications/channel_links_show_as_links_spec.js b/e2e-tests/cypress/tests/integration/channels/notifications/channel_links_show_as_links_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/notifications/channel_links_show_as_links_spec.js rename to e2e-tests/cypress/tests/integration/channels/notifications/channel_links_show_as_links_spec.js diff --git a/e2e/cypress/tests/integration/channels/notifications/deselect_username_mention_trigger_spec.js b/e2e-tests/cypress/tests/integration/channels/notifications/deselect_username_mention_trigger_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/notifications/deselect_username_mention_trigger_spec.js rename to e2e-tests/cypress/tests/integration/channels/notifications/deselect_username_mention_trigger_spec.js diff --git a/e2e/cypress/tests/integration/channels/notifications/desktop_notifications_1_spec.js b/e2e-tests/cypress/tests/integration/channels/notifications/desktop_notifications_1_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/notifications/desktop_notifications_1_spec.js rename to e2e-tests/cypress/tests/integration/channels/notifications/desktop_notifications_1_spec.js diff --git a/e2e/cypress/tests/integration/channels/notifications/desktop_notifications_2_spec.js b/e2e-tests/cypress/tests/integration/channels/notifications/desktop_notifications_2_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/notifications/desktop_notifications_2_spec.js rename to e2e-tests/cypress/tests/integration/channels/notifications/desktop_notifications_2_spec.js diff --git a/e2e/cypress/tests/integration/channels/notifications/desktop_notifications_3_spec.js b/e2e-tests/cypress/tests/integration/channels/notifications/desktop_notifications_3_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/notifications/desktop_notifications_3_spec.js rename to e2e-tests/cypress/tests/integration/channels/notifications/desktop_notifications_3_spec.js diff --git a/e2e/cypress/tests/integration/channels/notifications/direct_messages_do_not_add_indicator_spec.js b/e2e-tests/cypress/tests/integration/channels/notifications/direct_messages_do_not_add_indicator_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/notifications/direct_messages_do_not_add_indicator_spec.js rename to e2e-tests/cypress/tests/integration/channels/notifications/direct_messages_do_not_add_indicator_spec.js diff --git a/e2e/cypress/tests/integration/channels/notifications/helper.js b/e2e-tests/cypress/tests/integration/channels/notifications/helper.js similarity index 100% rename from e2e/cypress/tests/integration/channels/notifications/helper.js rename to e2e-tests/cypress/tests/integration/channels/notifications/helper.js diff --git a/e2e/cypress/tests/integration/channels/notifications/ignore_channel_mentions_spec.js b/e2e-tests/cypress/tests/integration/channels/notifications/ignore_channel_mentions_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/notifications/ignore_channel_mentions_spec.js rename to e2e-tests/cypress/tests/integration/channels/notifications/ignore_channel_mentions_spec.js diff --git a/e2e/cypress/tests/integration/channels/notifications/mention_email_notification_spec.js b/e2e-tests/cypress/tests/integration/channels/notifications/mention_email_notification_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/notifications/mention_email_notification_spec.js rename to e2e-tests/cypress/tests/integration/channels/notifications/mention_email_notification_spec.js diff --git a/e2e/cypress/tests/integration/channels/notifications/message_bar_spec.js b/e2e-tests/cypress/tests/integration/channels/notifications/message_bar_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/notifications/message_bar_spec.js rename to e2e-tests/cypress/tests/integration/channels/notifications/message_bar_spec.js diff --git a/e2e/cypress/tests/integration/channels/notifications/message_posted_while_scrolled_up_spec.js b/e2e-tests/cypress/tests/integration/channels/notifications/message_posted_while_scrolled_up_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/notifications/message_posted_while_scrolled_up_spec.js rename to e2e-tests/cypress/tests/integration/channels/notifications/message_posted_while_scrolled_up_spec.js diff --git a/e2e/cypress/tests/integration/channels/notifications/notification_preferences_do_not_save_spec.js b/e2e-tests/cypress/tests/integration/channels/notifications/notification_preferences_do_not_save_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/notifications/notification_preferences_do_not_save_spec.js rename to e2e-tests/cypress/tests/integration/channels/notifications/notification_preferences_do_not_save_spec.js diff --git a/e2e/cypress/tests/integration/channels/notifications/own_user_posts_reply_while_scrolled_up_spec.js b/e2e-tests/cypress/tests/integration/channels/notifications/own_user_posts_reply_while_scrolled_up_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/notifications/own_user_posts_reply_while_scrolled_up_spec.js rename to e2e-tests/cypress/tests/integration/channels/notifications/own_user_posts_reply_while_scrolled_up_spec.js diff --git a/e2e/cypress/tests/integration/channels/notifications/reply_notifications_spec.js b/e2e-tests/cypress/tests/integration/channels/notifications/reply_notifications_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/notifications/reply_notifications_spec.js rename to e2e-tests/cypress/tests/integration/channels/notifications/reply_notifications_spec.js diff --git a/e2e/cypress/tests/integration/channels/notifications/unread_on_public_channel_spec.js b/e2e-tests/cypress/tests/integration/channels/notifications/unread_on_public_channel_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/notifications/unread_on_public_channel_spec.js rename to e2e-tests/cypress/tests/integration/channels/notifications/unread_on_public_channel_spec.js diff --git a/e2e/cypress/tests/integration/channels/notifications/users_with_same_firstname_channel_mentions_spec.js b/e2e-tests/cypress/tests/integration/channels/notifications/users_with_same_firstname_channel_mentions_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/notifications/users_with_same_firstname_channel_mentions_spec.js rename to e2e-tests/cypress/tests/integration/channels/notifications/users_with_same_firstname_channel_mentions_spec.js diff --git a/e2e/cypress/tests/integration/channels/onboarding/existing_email_adress_spec.js b/e2e-tests/cypress/tests/integration/channels/onboarding/existing_email_adress_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/onboarding/existing_email_adress_spec.js rename to e2e-tests/cypress/tests/integration/channels/onboarding/existing_email_adress_spec.js diff --git a/e2e/cypress/tests/integration/channels/onboarding/invalidate_pending_email_invitations_spec.js b/e2e-tests/cypress/tests/integration/channels/onboarding/invalidate_pending_email_invitations_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/onboarding/invalidate_pending_email_invitations_spec.js rename to e2e-tests/cypress/tests/integration/channels/onboarding/invalidate_pending_email_invitations_spec.js diff --git a/e2e/cypress/tests/integration/channels/onboarding/login_page_link_account_creation_spec.js b/e2e-tests/cypress/tests/integration/channels/onboarding/login_page_link_account_creation_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/onboarding/login_page_link_account_creation_spec.js rename to e2e-tests/cypress/tests/integration/channels/onboarding/login_page_link_account_creation_spec.js diff --git a/e2e/cypress/tests/integration/channels/onboarding/use_team_invite_link_to_sign_up_spec.js b/e2e-tests/cypress/tests/integration/channels/onboarding/use_team_invite_link_to_sign_up_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/onboarding/use_team_invite_link_to_sign_up_spec.js rename to e2e-tests/cypress/tests/integration/channels/onboarding/use_team_invite_link_to_sign_up_spec.js diff --git a/e2e/cypress/tests/integration/channels/performance/channel_switch_spec.js b/e2e-tests/cypress/tests/integration/channels/performance/channel_switch_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/performance/channel_switch_spec.js rename to e2e-tests/cypress/tests/integration/channels/performance/channel_switch_spec.js diff --git a/e2e/cypress/tests/integration/channels/performance/team_switch_spec.js b/e2e-tests/cypress/tests/integration/channels/performance/team_switch_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/performance/team_switch_spec.js rename to e2e-tests/cypress/tests/integration/channels/performance/team_switch_spec.js diff --git a/e2e/cypress/tests/integration/channels/performance/utils.js b/e2e-tests/cypress/tests/integration/channels/performance/utils.js similarity index 100% rename from e2e/cypress/tests/integration/channels/performance/utils.js rename to e2e-tests/cypress/tests/integration/channels/performance/utils.js diff --git a/e2e/cypress/tests/integration/channels/plugins/demo_plugin/webhook_spec.js b/e2e-tests/cypress/tests/integration/channels/plugins/demo_plugin/webhook_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/plugins/demo_plugin/webhook_spec.js rename to e2e-tests/cypress/tests/integration/channels/plugins/demo_plugin/webhook_spec.js diff --git a/e2e/cypress/tests/integration/channels/plugins/helpers.js b/e2e-tests/cypress/tests/integration/channels/plugins/helpers.js similarity index 100% rename from e2e/cypress/tests/integration/channels/plugins/helpers.js rename to e2e-tests/cypress/tests/integration/channels/plugins/helpers.js diff --git a/e2e/cypress/tests/integration/channels/plugins/link_tooltip_spec.js b/e2e-tests/cypress/tests/integration/channels/plugins/link_tooltip_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/plugins/link_tooltip_spec.js rename to e2e-tests/cypress/tests/integration/channels/plugins/link_tooltip_spec.js diff --git a/e2e/cypress/tests/integration/channels/plugins/marketplace/disabled_remote_marketplace_spec.js b/e2e-tests/cypress/tests/integration/channels/plugins/marketplace/disabled_remote_marketplace_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/plugins/marketplace/disabled_remote_marketplace_spec.js rename to e2e-tests/cypress/tests/integration/channels/plugins/marketplace/disabled_remote_marketplace_spec.js diff --git a/e2e/cypress/tests/integration/channels/plugins/marketplace/helpers.js b/e2e-tests/cypress/tests/integration/channels/plugins/marketplace/helpers.js similarity index 100% rename from e2e/cypress/tests/integration/channels/plugins/marketplace/helpers.js rename to e2e-tests/cypress/tests/integration/channels/plugins/marketplace/helpers.js diff --git a/e2e/cypress/tests/integration/channels/plugins/marketplace/invalid_marketplace_url_spec.js b/e2e-tests/cypress/tests/integration/channels/plugins/marketplace/invalid_marketplace_url_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/plugins/marketplace/invalid_marketplace_url_spec.js rename to e2e-tests/cypress/tests/integration/channels/plugins/marketplace/invalid_marketplace_url_spec.js diff --git a/e2e/cypress/tests/integration/channels/plugins/marketplace/not_render_in_main_menu_spec.js b/e2e-tests/cypress/tests/integration/channels/plugins/marketplace/not_render_in_main_menu_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/plugins/marketplace/not_render_in_main_menu_spec.js rename to e2e-tests/cypress/tests/integration/channels/plugins/marketplace/not_render_in_main_menu_spec.js diff --git a/e2e/cypress/tests/integration/channels/plugins/marketplace/render_in_main_menu_spec.js b/e2e-tests/cypress/tests/integration/channels/plugins/marketplace/render_in_main_menu_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/plugins/marketplace/render_in_main_menu_spec.js rename to e2e-tests/cypress/tests/integration/channels/plugins/marketplace/render_in_main_menu_spec.js diff --git a/e2e/cypress/tests/integration/channels/plugins/marketplace/ui_spec.js b/e2e-tests/cypress/tests/integration/channels/plugins/marketplace/ui_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/plugins/marketplace/ui_spec.js rename to e2e-tests/cypress/tests/integration/channels/plugins/marketplace/ui_spec.js diff --git a/e2e/cypress/tests/integration/channels/plugins/plugin_buttons_spec.js b/e2e-tests/cypress/tests/integration/channels/plugins/plugin_buttons_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/plugins/plugin_buttons_spec.js rename to e2e-tests/cypress/tests/integration/channels/plugins/plugin_buttons_spec.js diff --git a/e2e/cypress/tests/integration/channels/plugins/plugin_install_spec.js b/e2e-tests/cypress/tests/integration/channels/plugins/plugin_install_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/plugins/plugin_install_spec.js rename to e2e-tests/cypress/tests/integration/channels/plugins/plugin_install_spec.js diff --git a/e2e/cypress/tests/integration/channels/plugins/plugin_startup_fail_spec.js b/e2e-tests/cypress/tests/integration/channels/plugins/plugin_startup_fail_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/plugins/plugin_startup_fail_spec.js rename to e2e-tests/cypress/tests/integration/channels/plugins/plugin_startup_fail_spec.js diff --git a/e2e/cypress/tests/integration/channels/plugins/upgrade_spec.js b/e2e-tests/cypress/tests/integration/channels/plugins/upgrade_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/plugins/upgrade_spec.js rename to e2e-tests/cypress/tests/integration/channels/plugins/upgrade_spec.js diff --git a/e2e/cypress/tests/integration/channels/profile_settings/profile_settings_spec.js b/e2e-tests/cypress/tests/integration/channels/profile_settings/profile_settings_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/profile_settings/profile_settings_spec.js rename to e2e-tests/cypress/tests/integration/channels/profile_settings/profile_settings_spec.js diff --git a/e2e/cypress/tests/integration/channels/scroll/channel_scroll_spec.js b/e2e-tests/cypress/tests/integration/channels/scroll/channel_scroll_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/scroll/channel_scroll_spec.js rename to e2e-tests/cypress/tests/integration/channels/scroll/channel_scroll_spec.js diff --git a/e2e/cypress/tests/integration/channels/scroll/default_images_collapsed_spec.js b/e2e-tests/cypress/tests/integration/channels/scroll/default_images_collapsed_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/scroll/default_images_collapsed_spec.js rename to e2e-tests/cypress/tests/integration/channels/scroll/default_images_collapsed_spec.js diff --git a/e2e/cypress/tests/integration/channels/scroll/deleting_image_scroll_spec.js b/e2e-tests/cypress/tests/integration/channels/scroll/deleting_image_scroll_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/scroll/deleting_image_scroll_spec.js rename to e2e-tests/cypress/tests/integration/channels/scroll/deleting_image_scroll_spec.js diff --git a/e2e/cypress/tests/integration/channels/scroll/deleting_scroll_spec.js b/e2e-tests/cypress/tests/integration/channels/scroll/deleting_scroll_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/scroll/deleting_scroll_spec.js rename to e2e-tests/cypress/tests/integration/channels/scroll/deleting_scroll_spec.js diff --git a/e2e/cypress/tests/integration/channels/scroll/editing_scroll_spec.js b/e2e-tests/cypress/tests/integration/channels/scroll/editing_scroll_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/scroll/editing_scroll_spec.js rename to e2e-tests/cypress/tests/integration/channels/scroll/editing_scroll_spec.js diff --git a/e2e/cypress/tests/integration/channels/scroll/fixed_width_spec.js b/e2e-tests/cypress/tests/integration/channels/scroll/fixed_width_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/scroll/fixed_width_spec.js rename to e2e-tests/cypress/tests/integration/channels/scroll/fixed_width_spec.js diff --git a/e2e/cypress/tests/integration/channels/scroll/helpers.js b/e2e-tests/cypress/tests/integration/channels/scroll/helpers.js similarity index 100% rename from e2e/cypress/tests/integration/channels/scroll/helpers.js rename to e2e-tests/cypress/tests/integration/channels/scroll/helpers.js diff --git a/e2e/cypress/tests/integration/channels/scroll/image_aspect_ratio_spec.js b/e2e-tests/cypress/tests/integration/channels/scroll/image_aspect_ratio_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/scroll/image_aspect_ratio_spec.js rename to e2e-tests/cypress/tests/integration/channels/scroll/image_aspect_ratio_spec.js diff --git a/e2e/cypress/tests/integration/channels/search/clear_input_spec.js b/e2e-tests/cypress/tests/integration/channels/search/clear_input_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/search/clear_input_spec.js rename to e2e-tests/cypress/tests/integration/channels/search/clear_input_spec.js diff --git a/e2e/cypress/tests/integration/channels/search/cleared_search_term_spec.js b/e2e-tests/cypress/tests/integration/channels/search/cleared_search_term_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/search/cleared_search_term_spec.js rename to e2e-tests/cypress/tests/integration/channels/search/cleared_search_term_spec.js diff --git a/e2e/cypress/tests/integration/channels/search/mobile_search_spec.js b/e2e-tests/cypress/tests/integration/channels/search/mobile_search_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/search/mobile_search_spec.js rename to e2e-tests/cypress/tests/integration/channels/search/mobile_search_spec.js diff --git a/e2e/cypress/tests/integration/channels/search/post_search_display_not_cloud_spec.js b/e2e-tests/cypress/tests/integration/channels/search/post_search_display_not_cloud_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/search/post_search_display_not_cloud_spec.js rename to e2e-tests/cypress/tests/integration/channels/search/post_search_display_not_cloud_spec.js diff --git a/e2e/cypress/tests/integration/channels/search/post_search_display_spec.js b/e2e-tests/cypress/tests/integration/channels/search/post_search_display_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/search/post_search_display_spec.js rename to e2e-tests/cypress/tests/integration/channels/search/post_search_display_spec.js diff --git a/e2e/cypress/tests/integration/channels/search/results_post_comment_spec.js b/e2e-tests/cypress/tests/integration/channels/search/results_post_comment_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/search/results_post_comment_spec.js rename to e2e-tests/cypress/tests/integration/channels/search/results_post_comment_spec.js diff --git a/e2e/cypress/tests/integration/channels/search/results_post_spec.js b/e2e-tests/cypress/tests/integration/channels/search/results_post_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/search/results_post_spec.js rename to e2e-tests/cypress/tests/integration/channels/search/results_post_spec.js diff --git a/e2e/cypress/tests/integration/channels/search/search_bar_popup_focus_spec.js b/e2e-tests/cypress/tests/integration/channels/search/search_bar_popup_focus_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/search/search_bar_popup_focus_spec.js rename to e2e-tests/cypress/tests/integration/channels/search/search_bar_popup_focus_spec.js diff --git a/e2e/cypress/tests/integration/channels/search/search_group_message_spec.js b/e2e-tests/cypress/tests/integration/channels/search/search_group_message_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/search/search_group_message_spec.js rename to e2e-tests/cypress/tests/integration/channels/search/search_group_message_spec.js diff --git a/e2e/cypress/tests/integration/channels/search/search_user_file_spec.js b/e2e-tests/cypress/tests/integration/channels/search/search_user_file_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/search/search_user_file_spec.js rename to e2e-tests/cypress/tests/integration/channels/search/search_user_file_spec.js diff --git a/e2e/cypress/tests/integration/channels/search/search_user_post_spec.js b/e2e-tests/cypress/tests/integration/channels/search/search_user_post_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/search/search_user_post_spec.js rename to e2e-tests/cypress/tests/integration/channels/search/search_user_post_spec.js diff --git a/e2e/cypress/tests/integration/channels/search_autocomplete/channels_spec.js b/e2e-tests/cypress/tests/integration/channels/search_autocomplete/channels_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/search_autocomplete/channels_spec.js rename to e2e-tests/cypress/tests/integration/channels/search_autocomplete/channels_spec.js diff --git a/e2e/cypress/tests/integration/channels/search_autocomplete/renaming_spec.js b/e2e-tests/cypress/tests/integration/channels/search_autocomplete/renaming_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/search_autocomplete/renaming_spec.js rename to e2e-tests/cypress/tests/integration/channels/search_autocomplete/renaming_spec.js diff --git a/e2e/cypress/tests/integration/channels/search_autocomplete/scroll_spec.js b/e2e-tests/cypress/tests/integration/channels/search_autocomplete/scroll_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/search_autocomplete/scroll_spec.js rename to e2e-tests/cypress/tests/integration/channels/search_autocomplete/scroll_spec.js diff --git a/e2e/cypress/tests/integration/channels/search_filter/after_spec.js b/e2e-tests/cypress/tests/integration/channels/search_filter/after_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/search_filter/after_spec.js rename to e2e-tests/cypress/tests/integration/channels/search_filter/after_spec.js diff --git a/e2e/cypress/tests/integration/channels/search_filter/before_spec.js b/e2e-tests/cypress/tests/integration/channels/search_filter/before_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/search_filter/before_spec.js rename to e2e-tests/cypress/tests/integration/channels/search_filter/before_spec.js diff --git a/e2e/cypress/tests/integration/channels/search_filter/edit_spec.js b/e2e-tests/cypress/tests/integration/channels/search_filter/edit_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/search_filter/edit_spec.js rename to e2e-tests/cypress/tests/integration/channels/search_filter/edit_spec.js diff --git a/e2e/cypress/tests/integration/channels/search_filter/future_date_spec.js b/e2e-tests/cypress/tests/integration/channels/search_filter/future_date_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/search_filter/future_date_spec.js rename to e2e-tests/cypress/tests/integration/channels/search_filter/future_date_spec.js diff --git a/e2e/cypress/tests/integration/channels/search_filter/helpers.js b/e2e-tests/cypress/tests/integration/channels/search_filter/helpers.js similarity index 100% rename from e2e/cypress/tests/integration/channels/search_filter/helpers.js rename to e2e-tests/cypress/tests/integration/channels/search_filter/helpers.js diff --git a/e2e/cypress/tests/integration/channels/search_filter/input_spec.js b/e2e-tests/cypress/tests/integration/channels/search_filter/input_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/search_filter/input_spec.js rename to e2e-tests/cypress/tests/integration/channels/search_filter/input_spec.js diff --git a/e2e/cypress/tests/integration/channels/search_filter/invalid_spec.js b/e2e-tests/cypress/tests/integration/channels/search_filter/invalid_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/search_filter/invalid_spec.js rename to e2e-tests/cypress/tests/integration/channels/search_filter/invalid_spec.js diff --git a/e2e/cypress/tests/integration/channels/search_filter/mixed_spec.js b/e2e-tests/cypress/tests/integration/channels/search_filter/mixed_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/search_filter/mixed_spec.js rename to e2e-tests/cypress/tests/integration/channels/search_filter/mixed_spec.js diff --git a/e2e/cypress/tests/integration/channels/search_filter/negative_spec.js b/e2e-tests/cypress/tests/integration/channels/search_filter/negative_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/search_filter/negative_spec.js rename to e2e-tests/cypress/tests/integration/channels/search_filter/negative_spec.js diff --git a/e2e/cypress/tests/integration/channels/search_filter/on_spec.js b/e2e-tests/cypress/tests/integration/channels/search_filter/on_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/search_filter/on_spec.js rename to e2e-tests/cypress/tests/integration/channels/search_filter/on_spec.js diff --git a/e2e/cypress/tests/integration/channels/settings/display/channel_display_mode_spec.js b/e2e-tests/cypress/tests/integration/channels/settings/display/channel_display_mode_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/settings/display/channel_display_mode_spec.js rename to e2e-tests/cypress/tests/integration/channels/settings/display/channel_display_mode_spec.js diff --git a/e2e/cypress/tests/integration/channels/settings/display/clock_display_mode_spec.js b/e2e-tests/cypress/tests/integration/channels/settings/display/clock_display_mode_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/settings/display/clock_display_mode_spec.js rename to e2e-tests/cypress/tests/integration/channels/settings/display/clock_display_mode_spec.js diff --git a/e2e/cypress/tests/integration/channels/settings/display/message_display_mode_colorize_username_spec.js b/e2e-tests/cypress/tests/integration/channels/settings/display/message_display_mode_colorize_username_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/settings/display/message_display_mode_colorize_username_spec.js rename to e2e-tests/cypress/tests/integration/channels/settings/display/message_display_mode_colorize_username_spec.js diff --git a/e2e/cypress/tests/integration/channels/settings/display/message_display_mode_spec.js b/e2e-tests/cypress/tests/integration/channels/settings/display/message_display_mode_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/settings/display/message_display_mode_spec.js rename to e2e-tests/cypress/tests/integration/channels/settings/display/message_display_mode_spec.js diff --git a/e2e/cypress/tests/integration/channels/settings/display/theme/code_theme_colors_spec.js b/e2e-tests/cypress/tests/integration/channels/settings/display/theme/code_theme_colors_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/settings/display/theme/code_theme_colors_spec.js rename to e2e-tests/cypress/tests/integration/channels/settings/display/theme/code_theme_colors_spec.js diff --git a/e2e/cypress/tests/integration/channels/settings/display/theme/custom_theme_color_picker_spec.js b/e2e-tests/cypress/tests/integration/channels/settings/display/theme/custom_theme_color_picker_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/settings/display/theme/custom_theme_color_picker_spec.js rename to e2e-tests/cypress/tests/integration/channels/settings/display/theme/custom_theme_color_picker_spec.js diff --git a/e2e/cypress/tests/integration/channels/settings/display/theme/custom_theme_sidebar_styles_spec.js b/e2e-tests/cypress/tests/integration/channels/settings/display/theme/custom_theme_sidebar_styles_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/settings/display/theme/custom_theme_sidebar_styles_spec.js rename to e2e-tests/cypress/tests/integration/channels/settings/display/theme/custom_theme_sidebar_styles_spec.js diff --git a/e2e/cypress/tests/integration/channels/settings/display/theme/save_theme_spec.js b/e2e-tests/cypress/tests/integration/channels/settings/display/theme/save_theme_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/settings/display/theme/save_theme_spec.js rename to e2e-tests/cypress/tests/integration/channels/settings/display/theme/save_theme_spec.js diff --git a/e2e/cypress/tests/integration/channels/settings/display/theme/settings_view_spec.js b/e2e-tests/cypress/tests/integration/channels/settings/display/theme/settings_view_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/settings/display/theme/settings_view_spec.js rename to e2e-tests/cypress/tests/integration/channels/settings/display/theme/settings_view_spec.js diff --git a/e2e/cypress/tests/integration/channels/settings/display/timezone_display_mode_spec.js b/e2e-tests/cypress/tests/integration/channels/settings/display/timezone_display_mode_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/settings/display/timezone_display_mode_spec.js rename to e2e-tests/cypress/tests/integration/channels/settings/display/timezone_display_mode_spec.js diff --git a/e2e/cypress/tests/integration/channels/settings/sidebar/channel_switcher_not_cloud_spec.js b/e2e-tests/cypress/tests/integration/channels/settings/sidebar/channel_switcher_not_cloud_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/settings/sidebar/channel_switcher_not_cloud_spec.js rename to e2e-tests/cypress/tests/integration/channels/settings/sidebar/channel_switcher_not_cloud_spec.js diff --git a/e2e/cypress/tests/integration/channels/settings/sidebar/channel_switcher_spec.js b/e2e-tests/cypress/tests/integration/channels/settings/sidebar/channel_switcher_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/settings/sidebar/channel_switcher_spec.js rename to e2e-tests/cypress/tests/integration/channels/settings/sidebar/channel_switcher_spec.js diff --git a/e2e/cypress/tests/integration/channels/settings/sidebar/fullname_spec.js b/e2e-tests/cypress/tests/integration/channels/settings/sidebar/fullname_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/settings/sidebar/fullname_spec.js rename to e2e-tests/cypress/tests/integration/channels/settings/sidebar/fullname_spec.js diff --git a/e2e/cypress/tests/integration/channels/signin_authentication/authentication_spec.js b/e2e-tests/cypress/tests/integration/channels/signin_authentication/authentication_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/signin_authentication/authentication_spec.js rename to e2e-tests/cypress/tests/integration/channels/signin_authentication/authentication_spec.js diff --git a/e2e/cypress/tests/integration/channels/signin_authentication/desktop_session_expire_spec.js b/e2e-tests/cypress/tests/integration/channels/signin_authentication/desktop_session_expire_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/signin_authentication/desktop_session_expire_spec.js rename to e2e-tests/cypress/tests/integration/channels/signin_authentication/desktop_session_expire_spec.js diff --git a/e2e/cypress/tests/integration/channels/signin_authentication/forgot_password_spec.js b/e2e-tests/cypress/tests/integration/channels/signin_authentication/forgot_password_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/signin_authentication/forgot_password_spec.js rename to e2e-tests/cypress/tests/integration/channels/signin_authentication/forgot_password_spec.js diff --git a/e2e/cypress/tests/integration/channels/signin_authentication/helpers.js b/e2e-tests/cypress/tests/integration/channels/signin_authentication/helpers.js similarity index 100% rename from e2e/cypress/tests/integration/channels/signin_authentication/helpers.js rename to e2e-tests/cypress/tests/integration/channels/signin_authentication/helpers.js diff --git a/e2e/cypress/tests/integration/channels/signin_authentication/login_close_server_spec.js b/e2e-tests/cypress/tests/integration/channels/signin_authentication/login_close_server_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/signin_authentication/login_close_server_spec.js rename to e2e-tests/cypress/tests/integration/channels/signin_authentication/login_close_server_spec.js diff --git a/e2e/cypress/tests/integration/channels/signin_authentication/login_logout_smoke_spec.js b/e2e-tests/cypress/tests/integration/channels/signin_authentication/login_logout_smoke_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/signin_authentication/login_logout_smoke_spec.js rename to e2e-tests/cypress/tests/integration/channels/signin_authentication/login_logout_smoke_spec.js diff --git a/e2e/cypress/tests/integration/channels/signin_authentication/login_open_server_spec.js b/e2e-tests/cypress/tests/integration/channels/signin_authentication/login_open_server_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/signin_authentication/login_open_server_spec.js rename to e2e-tests/cypress/tests/integration/channels/signin_authentication/login_open_server_spec.js diff --git a/e2e/cypress/tests/integration/channels/signin_authentication/mfa_authentication_spec.js b/e2e-tests/cypress/tests/integration/channels/signin_authentication/mfa_authentication_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/signin_authentication/mfa_authentication_spec.js rename to e2e-tests/cypress/tests/integration/channels/signin_authentication/mfa_authentication_spec.js diff --git a/e2e/cypress/tests/integration/channels/signin_authentication/signup_spec.js b/e2e-tests/cypress/tests/integration/channels/signin_authentication/signup_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/signin_authentication/signup_spec.js rename to e2e-tests/cypress/tests/integration/channels/signin_authentication/signup_spec.js diff --git a/e2e/cypress/tests/integration/channels/slash_commands/autocomplete_spec.js b/e2e-tests/cypress/tests/integration/channels/slash_commands/autocomplete_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/slash_commands/autocomplete_spec.js rename to e2e-tests/cypress/tests/integration/channels/slash_commands/autocomplete_spec.js diff --git a/e2e/cypress/tests/integration/channels/status/status_dnd_1_spec.js b/e2e-tests/cypress/tests/integration/channels/status/status_dnd_1_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/status/status_dnd_1_spec.js rename to e2e-tests/cypress/tests/integration/channels/status/status_dnd_1_spec.js diff --git a/e2e/cypress/tests/integration/channels/subpath/subpath_channel_routing_spec.js b/e2e-tests/cypress/tests/integration/channels/subpath/subpath_channel_routing_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/subpath/subpath_channel_routing_spec.js rename to e2e-tests/cypress/tests/integration/channels/subpath/subpath_channel_routing_spec.js diff --git a/e2e/cypress/tests/integration/channels/subpath/subpath_dm_search_spec.js b/e2e-tests/cypress/tests/integration/channels/subpath/subpath_dm_search_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/subpath/subpath_dm_search_spec.js rename to e2e-tests/cypress/tests/integration/channels/subpath/subpath_dm_search_spec.js diff --git a/e2e/cypress/tests/integration/channels/subpath/subpath_login_spec.js b/e2e-tests/cypress/tests/integration/channels/subpath/subpath_login_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/subpath/subpath_login_spec.js rename to e2e-tests/cypress/tests/integration/channels/subpath/subpath_login_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/authentication/password_settings_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/authentication/password_settings_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/authentication/password_settings_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/authentication/password_settings_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/compliance/custom_terms_of_service_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/compliance/custom_terms_of_service_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/compliance/custom_terms_of_service_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/compliance/custom_terms_of_service_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/demoted_user_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/demoted_user_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/demoted_user_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/demoted_user_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/environment_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/environment_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/environment_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/environment_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/feature_discovery_cloud_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/feature_discovery_cloud_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/feature_discovery_cloud_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/feature_discovery_cloud_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/feature_discovery_not_cloud_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/feature_discovery_not_cloud_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/feature_discovery_not_cloud_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/feature_discovery_not_cloud_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/feature_discovery_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/feature_discovery_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/feature_discovery_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/feature_discovery_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/inactive_users_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/inactive_users_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/inactive_users_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/inactive_users_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/lock_teammate_name_display_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/lock_teammate_name_display_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/lock_teammate_name_display_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/lock_teammate_name_display_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/main_menu_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/main_menu_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/main_menu_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/main_menu_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/mobile_settings_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/mobile_settings_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/mobile_settings_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/mobile_settings_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/plugin_marketplace_url_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/plugin_marketplace_url_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/plugin_marketplace_url_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/plugin_marketplace_url_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/reporting/server_logs_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/reporting/server_logs_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/reporting/server_logs_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/reporting/server_logs_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/reporting/site_statistics_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/reporting/site_statistics_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/reporting/site_statistics_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/reporting/site_statistics_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/reporting/site_statistics_te_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/reporting/site_statistics_te_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/reporting/site_statistics_te_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/reporting/site_statistics_te_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/reporting/team_statistics_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/reporting/team_statistics_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/reporting/team_statistics_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/reporting/team_statistics_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/revoke_all_sessions_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/revoke_all_sessions_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/revoke_all_sessions_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/revoke_all_sessions_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/search_box_not_cloud_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/search_box_not_cloud_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/search_box_not_cloud_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/search_box_not_cloud_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/session_length_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/session_length_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/session_length_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/session_length_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/sidebar_link_navigation_team_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/sidebar_link_navigation_team_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/sidebar_link_navigation_team_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/sidebar_link_navigation_team_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/site_configuration/announcement_banner_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/site_configuration/announcement_banner_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/site_configuration/announcement_banner_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/site_configuration/announcement_banner_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/site_configuration/customization_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/site_configuration/customization_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/site_configuration/customization_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/site_configuration/customization_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/site_configuration/helper.js b/e2e-tests/cypress/tests/integration/channels/system_console/site_configuration/helper.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/site_configuration/helper.js rename to e2e-tests/cypress/tests/integration/channels/system_console/site_configuration/helper.js diff --git a/e2e/cypress/tests/integration/channels/system_console/site_configuration/link_customization_cloud_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/site_configuration/link_customization_cloud_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/site_configuration/link_customization_cloud_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/site_configuration/link_customization_cloud_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/site_configuration/link_customization_e20_1_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/site_configuration/link_customization_e20_1_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/site_configuration/link_customization_e20_1_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/site_configuration/link_customization_e20_1_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/site_configuration/link_customization_e20_2_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/site_configuration/link_customization_e20_2_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/site_configuration/link_customization_e20_2_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/site_configuration/link_customization_e20_2_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/site_url_config_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/site_url_config_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/site_url_config_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/site_url_config_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/support_packet_generation_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/support_packet_generation_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/support_packet_generation_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/support_packet_generation_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/true_up_review_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/true_up_review_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/true_up_review_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/true_up_review_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/ui_and_api/custom_site_name_description_spec.ts b/e2e-tests/cypress/tests/integration/channels/system_console/ui_and_api/custom_site_name_description_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/ui_and_api/custom_site_name_description_spec.ts rename to e2e-tests/cypress/tests/integration/channels/system_console/ui_and_api/custom_site_name_description_spec.ts diff --git a/e2e/cypress/tests/integration/channels/system_console/ui_and_api/customization_not_cloud_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/ui_and_api/customization_not_cloud_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/ui_and_api/customization_not_cloud_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/ui_and_api/customization_not_cloud_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/ui_and_api/customization_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/ui_and_api/customization_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/ui_and_api/customization_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/ui_and_api/customization_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/unsaved_changes_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/unsaved_changes_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/unsaved_changes_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/unsaved_changes_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/user_management/users_deactivation_1_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/user_management/users_deactivation_1_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/user_management/users_deactivation_1_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/user_management/users_deactivation_1_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/user_management/users_deactivation_not_cloud_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/user_management/users_deactivation_not_cloud_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/user_management/users_deactivation_not_cloud_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/user_management/users_deactivation_not_cloud_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/user_management/users_deactivation_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/user_management/users_deactivation_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/user_management/users_deactivation_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/user_management/users_deactivation_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/user_management/users_reactivation_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/user_management/users_reactivation_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/user_management/users_reactivation_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/user_management/users_reactivation_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/user_management/users_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/user_management/users_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/user_management/users_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/user_management/users_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/user_management_not_cloud_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/user_management_not_cloud_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/user_management_not_cloud_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/user_management_not_cloud_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/user_management_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/user_management_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/user_management_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/user_management_spec.js diff --git a/e2e/cypress/tests/integration/channels/system_console/workspace_deletion_spec.js b/e2e-tests/cypress/tests/integration/channels/system_console/workspace_deletion_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/system_console/workspace_deletion_spec.js rename to e2e-tests/cypress/tests/integration/channels/system_console/workspace_deletion_spec.js diff --git a/e2e/cypress/tests/integration/channels/team_settings/archive_team_spec.ts b/e2e-tests/cypress/tests/integration/channels/team_settings/archive_team_spec.ts similarity index 100% rename from e2e/cypress/tests/integration/channels/team_settings/archive_team_spec.ts rename to e2e-tests/cypress/tests/integration/channels/team_settings/archive_team_spec.ts diff --git a/e2e/cypress/tests/integration/channels/team_settings/closed_team_invite_by_email_spec.js b/e2e-tests/cypress/tests/integration/channels/team_settings/closed_team_invite_by_email_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/team_settings/closed_team_invite_by_email_spec.js rename to e2e-tests/cypress/tests/integration/channels/team_settings/closed_team_invite_by_email_spec.js diff --git a/e2e/cypress/tests/integration/channels/team_settings/closed_team_invite_with_non_mattermost_domain_spec.js b/e2e-tests/cypress/tests/integration/channels/team_settings/closed_team_invite_with_non_mattermost_domain_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/team_settings/closed_team_invite_with_non_mattermost_domain_spec.js rename to e2e-tests/cypress/tests/integration/channels/team_settings/closed_team_invite_with_non_mattermost_domain_spec.js diff --git a/e2e/cypress/tests/integration/channels/team_settings/closed_team_invite_with_specific_domain_spec.js b/e2e-tests/cypress/tests/integration/channels/team_settings/closed_team_invite_with_specific_domain_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/team_settings/closed_team_invite_with_specific_domain_spec.js rename to e2e-tests/cypress/tests/integration/channels/team_settings/closed_team_invite_with_specific_domain_spec.js diff --git a/e2e/cypress/tests/integration/channels/team_settings/create_a_team_spec.js b/e2e-tests/cypress/tests/integration/channels/team_settings/create_a_team_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/team_settings/create_a_team_spec.js rename to e2e-tests/cypress/tests/integration/channels/team_settings/create_a_team_spec.js diff --git a/e2e/cypress/tests/integration/channels/team_settings/helpers.js b/e2e-tests/cypress/tests/integration/channels/team_settings/helpers.js similarity index 100% rename from e2e/cypress/tests/integration/channels/team_settings/helpers.js rename to e2e-tests/cypress/tests/integration/channels/team_settings/helpers.js diff --git a/e2e/cypress/tests/integration/channels/team_settings/invite_members_backdrop_spec.js b/e2e-tests/cypress/tests/integration/channels/team_settings/invite_members_backdrop_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/team_settings/invite_members_backdrop_spec.js rename to e2e-tests/cypress/tests/integration/channels/team_settings/invite_members_backdrop_spec.js diff --git a/e2e/cypress/tests/integration/channels/team_settings/invite_members_spec.js b/e2e-tests/cypress/tests/integration/channels/team_settings/invite_members_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/team_settings/invite_members_spec.js rename to e2e-tests/cypress/tests/integration/channels/team_settings/invite_members_spec.js diff --git a/e2e/cypress/tests/integration/channels/team_settings/invite_user_to_closed_team_spec.js b/e2e-tests/cypress/tests/integration/channels/team_settings/invite_user_to_closed_team_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/team_settings/invite_user_to_closed_team_spec.js rename to e2e-tests/cypress/tests/integration/channels/team_settings/invite_user_to_closed_team_spec.js diff --git a/e2e/cypress/tests/integration/channels/team_settings/join_closed_team_with_not_allowed_email_spec.js b/e2e-tests/cypress/tests/integration/channels/team_settings/join_closed_team_with_not_allowed_email_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/team_settings/join_closed_team_with_not_allowed_email_spec.js rename to e2e-tests/cypress/tests/integration/channels/team_settings/join_closed_team_with_not_allowed_email_spec.js diff --git a/e2e/cypress/tests/integration/channels/team_settings/manage_members_spec.js b/e2e-tests/cypress/tests/integration/channels/team_settings/manage_members_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/team_settings/manage_members_spec.js rename to e2e-tests/cypress/tests/integration/channels/team_settings/manage_members_spec.js diff --git a/e2e/cypress/tests/integration/channels/team_settings/remove_team_icon_spec.js b/e2e-tests/cypress/tests/integration/channels/team_settings/remove_team_icon_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/team_settings/remove_team_icon_spec.js rename to e2e-tests/cypress/tests/integration/channels/team_settings/remove_team_icon_spec.js diff --git a/e2e/cypress/tests/integration/channels/team_settings/teammates_pagination_spec.js b/e2e-tests/cypress/tests/integration/channels/team_settings/teammates_pagination_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/team_settings/teammates_pagination_spec.js rename to e2e-tests/cypress/tests/integration/channels/team_settings/teammates_pagination_spec.js diff --git a/e2e/cypress/tests/integration/channels/team_settings/teams_spec.js b/e2e-tests/cypress/tests/integration/channels/team_settings/teams_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/team_settings/teams_spec.js rename to e2e-tests/cypress/tests/integration/channels/team_settings/teams_spec.js diff --git a/e2e/cypress/tests/integration/channels/toast/helpers.js b/e2e-tests/cypress/tests/integration/channels/toast/helpers.js similarity index 100% rename from e2e/cypress/tests/integration/channels/toast/helpers.js rename to e2e-tests/cypress/tests/integration/channels/toast/helpers.js diff --git a/e2e/cypress/tests/integration/channels/toast/new_messages_toast_spec.js b/e2e-tests/cypress/tests/integration/channels/toast/new_messages_toast_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/toast/new_messages_toast_spec.js rename to e2e-tests/cypress/tests/integration/channels/toast/new_messages_toast_spec.js diff --git a/e2e/cypress/tests/integration/channels/toast/permalink_jump_to_spec.js b/e2e-tests/cypress/tests/integration/channels/toast/permalink_jump_to_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/toast/permalink_jump_to_spec.js rename to e2e-tests/cypress/tests/integration/channels/toast/permalink_jump_to_spec.js diff --git a/e2e/cypress/tests/integration/channels/toast/permalink_post_spec.js b/e2e-tests/cypress/tests/integration/channels/toast/permalink_post_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/toast/permalink_post_spec.js rename to e2e-tests/cypress/tests/integration/channels/toast/permalink_post_spec.js diff --git a/e2e/cypress/tests/integration/channels/toast/permalink_post_with_new_message_spec.js b/e2e-tests/cypress/tests/integration/channels/toast/permalink_post_with_new_message_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/toast/permalink_post_with_new_message_spec.js rename to e2e-tests/cypress/tests/integration/channels/toast/permalink_post_with_new_message_spec.js diff --git a/e2e/cypress/tests/integration/channels/toast/toast_spec.js b/e2e-tests/cypress/tests/integration/channels/toast/toast_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/toast/toast_spec.js rename to e2e-tests/cypress/tests/integration/channels/toast/toast_spec.js diff --git a/e2e/cypress/tests/integration/channels/toast/unread_with_bottom_start_toast_spec.js b/e2e-tests/cypress/tests/integration/channels/toast/unread_with_bottom_start_toast_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/toast/unread_with_bottom_start_toast_spec.js rename to e2e-tests/cypress/tests/integration/channels/toast/unread_with_bottom_start_toast_spec.js diff --git a/e2e/cypress/tests/integration/channels/websocket/channel_created/new_sidebar_spec.js b/e2e-tests/cypress/tests/integration/channels/websocket/channel_created/new_sidebar_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/websocket/channel_created/new_sidebar_spec.js rename to e2e-tests/cypress/tests/integration/channels/websocket/channel_created/new_sidebar_spec.js diff --git a/e2e/cypress/tests/integration/channels/websocket/channel_created/old_sidebar_spec.js b/e2e-tests/cypress/tests/integration/channels/websocket/channel_created/old_sidebar_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/websocket/channel_created/old_sidebar_spec.js rename to e2e-tests/cypress/tests/integration/channels/websocket/channel_created/old_sidebar_spec.js diff --git a/e2e/cypress/tests/integration/channels/websocket/handle_new_post_spec.js b/e2e-tests/cypress/tests/integration/channels/websocket/handle_new_post_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/websocket/handle_new_post_spec.js rename to e2e-tests/cypress/tests/integration/channels/websocket/handle_new_post_spec.js diff --git a/e2e/cypress/tests/integration/channels/websocket/handle_removed_user/helpers.js b/e2e-tests/cypress/tests/integration/channels/websocket/handle_removed_user/helpers.js similarity index 100% rename from e2e/cypress/tests/integration/channels/websocket/handle_removed_user/helpers.js rename to e2e-tests/cypress/tests/integration/channels/websocket/handle_removed_user/helpers.js diff --git a/e2e/cypress/tests/integration/channels/websocket/handle_removed_user/new_sidebar_spec.js b/e2e-tests/cypress/tests/integration/channels/websocket/handle_removed_user/new_sidebar_spec.js similarity index 100% rename from e2e/cypress/tests/integration/channels/websocket/handle_removed_user/new_sidebar_spec.js rename to e2e-tests/cypress/tests/integration/channels/websocket/handle_removed_user/new_sidebar_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/adminconsole/analytics_spec.js b/e2e-tests/cypress/tests/integration/playbooks/adminconsole/analytics_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/adminconsole/analytics_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/adminconsole/analytics_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/api/runs_spec.js b/e2e-tests/cypress/tests/integration/playbooks/api/runs_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/api/runs_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/api/runs_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/channels/app_bar_spec.js b/e2e-tests/cypress/tests/integration/playbooks/channels/app_bar_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/channels/app_bar_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/channels/app_bar_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/channels/broadcast_spec.js b/e2e-tests/cypress/tests/integration/playbooks/channels/broadcast_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/channels/broadcast_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/channels/broadcast_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/channels/channel_header_spec.js b/e2e-tests/cypress/tests/integration/playbooks/channels/channel_header_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/channels/channel_header_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/channels/channel_header_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/channels/general_actions_spec.js b/e2e-tests/cypress/tests/integration/playbooks/channels/general_actions_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/channels/general_actions_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/channels/general_actions_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/channels/playbook_run_actions.js b/e2e-tests/cypress/tests/integration/playbooks/channels/playbook_run_actions.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/channels/playbook_run_actions.js rename to e2e-tests/cypress/tests/integration/playbooks/channels/playbook_run_actions.js diff --git a/e2e/cypress/tests/integration/playbooks/channels/post_type_components_spec.js b/e2e-tests/cypress/tests/integration/playbooks/channels/post_type_components_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/channels/post_type_components_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/channels/post_type_components_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/channels/retrospective_spec.js b/e2e-tests/cypress/tests/integration/playbooks/channels/retrospective_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/channels/retrospective_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/channels/retrospective_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/channels/rhs/about_spec.js b/e2e-tests/cypress/tests/integration/playbooks/channels/rhs/about_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/channels/rhs/about_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/channels/rhs/about_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/channels/rhs/checklist_spec.js b/e2e-tests/cypress/tests/integration/playbooks/channels/rhs/checklist_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/channels/rhs/checklist_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/channels/rhs/checklist_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/channels/rhs/header_spec.js b/e2e-tests/cypress/tests/integration/playbooks/channels/rhs/header_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/channels/rhs/header_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/channels/rhs/header_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/channels/rhs/home_spec.js b/e2e-tests/cypress/tests/integration/playbooks/channels/rhs/home_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/channels/rhs/home_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/channels/rhs/home_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/channels/rhs/list_spec.js b/e2e-tests/cypress/tests/integration/playbooks/channels/rhs/list_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/channels/rhs/list_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/channels/rhs/list_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/channels/rhs/start_run_rhs_spec.js b/e2e-tests/cypress/tests/integration/playbooks/channels/rhs/start_run_rhs_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/channels/rhs/start_run_rhs_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/channels/rhs/start_run_rhs_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/channels/rhs/status_update_spec.js b/e2e-tests/cypress/tests/integration/playbooks/channels/rhs/status_update_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/channels/rhs/status_update_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/channels/rhs/status_update_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/channels/rhs/template_spec.js b/e2e-tests/cypress/tests/integration/playbooks/channels/rhs/template_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/channels/rhs/template_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/channels/rhs/template_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/channels/rhs/title_spec.js b/e2e-tests/cypress/tests/integration/playbooks/channels/rhs/title_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/channels/rhs/title_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/channels/rhs/title_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/channels/rhs_spec.js b/e2e-tests/cypress/tests/integration/playbooks/channels/rhs_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/channels/rhs_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/channels/rhs_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/channels/run_dialog_spec.js b/e2e-tests/cypress/tests/integration/playbooks/channels/run_dialog_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/channels/run_dialog_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/channels/run_dialog_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/channels/run_spec.js b/e2e-tests/cypress/tests/integration/playbooks/channels/run_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/channels/run_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/channels/run_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/channels/slash_command/commands_spec.js b/e2e-tests/cypress/tests/integration/playbooks/channels/slash_command/commands_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/channels/slash_command/commands_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/channels/slash_command/commands_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/channels/slash_command/info_spec.js b/e2e-tests/cypress/tests/integration/playbooks/channels/slash_command/info_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/channels/slash_command/info_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/channels/slash_command/info_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/channels/slash_command/owner_spec.js b/e2e-tests/cypress/tests/integration/playbooks/channels/slash_command/owner_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/channels/slash_command/owner_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/channels/slash_command/owner_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/channels/slash_command/test_spec.js b/e2e-tests/cypress/tests/integration/playbooks/channels/slash_command/test_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/channels/slash_command/test_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/channels/slash_command/test_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/channels/slash_command/todo_spec.js b/e2e-tests/cypress/tests/integration/playbooks/channels/slash_command/todo_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/channels/slash_command/todo_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/channels/slash_command/todo_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/channels/update_request_post_spec.js b/e2e-tests/cypress/tests/integration/playbooks/channels/update_request_post_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/channels/update_request_post_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/channels/update_request_post_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/digest_spec.js b/e2e-tests/cypress/tests/integration/playbooks/digest_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/digest_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/digest_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/lhs_spec.js b/e2e-tests/cypress/tests/integration/playbooks/lhs_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/lhs_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/lhs_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/navigation_spec.js b/e2e-tests/cypress/tests/integration/playbooks/navigation_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/navigation_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/navigation_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/playbooks/access_spec.js b/e2e-tests/cypress/tests/integration/playbooks/playbooks/access_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/playbooks/access_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/playbooks/access_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/playbooks/creation_button_spec.js b/e2e-tests/cypress/tests/integration/playbooks/playbooks/creation_button_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/playbooks/creation_button_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/playbooks/creation_button_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/playbooks/edit/task_actions_spec.js b/e2e-tests/cypress/tests/integration/playbooks/playbooks/edit/task_actions_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/playbooks/edit/task_actions_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/playbooks/edit/task_actions_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/playbooks/edit_metrics_spec.js b/e2e-tests/cypress/tests/integration/playbooks/playbooks/edit_metrics_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/playbooks/edit_metrics_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/playbooks/edit_metrics_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/playbooks/edit_spec.js b/e2e-tests/cypress/tests/integration/playbooks/playbooks/edit_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/playbooks/edit_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/playbooks/edit_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/playbooks/feedback_spec.js b/e2e-tests/cypress/tests/integration/playbooks/playbooks/feedback_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/playbooks/feedback_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/playbooks/feedback_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/playbooks/list_spec.js b/e2e-tests/cypress/tests/integration/playbooks/playbooks/list_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/playbooks/list_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/playbooks/list_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/playbooks/overview_spec.js b/e2e-tests/cypress/tests/integration/playbooks/playbooks/overview_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/playbooks/overview_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/playbooks/overview_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/playbooks/pagination_spec.js b/e2e-tests/cypress/tests/integration/playbooks/playbooks/pagination_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/playbooks/pagination_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/playbooks/pagination_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/playbooks/start_run_spec.js b/e2e-tests/cypress/tests/integration/playbooks/playbooks/start_run_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/playbooks/start_run_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/playbooks/start_run_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/playbooks/status_update_spec.js b/e2e-tests/cypress/tests/integration/playbooks/playbooks/status_update_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/playbooks/status_update_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/playbooks/status_update_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/runs/list_spec.js b/e2e-tests/cypress/tests/integration/playbooks/runs/list_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/runs/list_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/runs/list_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/runs/permissions_spec.js b/e2e-tests/cypress/tests/integration/playbooks/runs/permissions_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/runs/permissions_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/runs/permissions_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/runs/rdp_general_spec.js b/e2e-tests/cypress/tests/integration/playbooks/runs/rdp_general_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/runs/rdp_general_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/runs/rdp_general_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/runs/rdp_main_checklist_spec.js b/e2e-tests/cypress/tests/integration/playbooks/runs/rdp_main_checklist_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/runs/rdp_main_checklist_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/runs/rdp_main_checklist_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/runs/rdp_main_finish_spec.js b/e2e-tests/cypress/tests/integration/playbooks/runs/rdp_main_finish_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/runs/rdp_main_finish_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/runs/rdp_main_finish_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/runs/rdp_main_header_spec.js b/e2e-tests/cypress/tests/integration/playbooks/runs/rdp_main_header_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/runs/rdp_main_header_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/runs/rdp_main_header_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/runs/rdp_main_restore_spec.js b/e2e-tests/cypress/tests/integration/playbooks/runs/rdp_main_restore_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/runs/rdp_main_restore_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/runs/rdp_main_restore_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/runs/rdp_main_retrospective_spec.js b/e2e-tests/cypress/tests/integration/playbooks/runs/rdp_main_retrospective_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/runs/rdp_main_retrospective_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/runs/rdp_main_retrospective_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/runs/rdp_main_statusupdate_spec.js b/e2e-tests/cypress/tests/integration/playbooks/runs/rdp_main_statusupdate_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/runs/rdp_main_statusupdate_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/runs/rdp_main_statusupdate_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/runs/rdp_main_summary_spec.js b/e2e-tests/cypress/tests/integration/playbooks/runs/rdp_main_summary_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/runs/rdp_main_summary_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/runs/rdp_main_summary_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/runs/rdp_main_taskactions_spec.js b/e2e-tests/cypress/tests/integration/playbooks/runs/rdp_main_taskactions_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/runs/rdp_main_taskactions_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/runs/rdp_main_taskactions_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/runs/rdp_rhs_participants_spec.js b/e2e-tests/cypress/tests/integration/playbooks/runs/rdp_rhs_participants_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/runs/rdp_rhs_participants_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/runs/rdp_rhs_participants_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/runs/rdp_rhs_runinfo_spec.js b/e2e-tests/cypress/tests/integration/playbooks/runs/rdp_rhs_runinfo_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/runs/rdp_rhs_runinfo_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/runs/rdp_rhs_runinfo_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/runs/rdp_rhs_spec.js b/e2e-tests/cypress/tests/integration/playbooks/runs/rdp_rhs_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/runs/rdp_rhs_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/runs/rdp_rhs_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/runs/rdp_rhs_statusupdates_spec.js b/e2e-tests/cypress/tests/integration/playbooks/runs/rdp_rhs_statusupdates_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/runs/rdp_rhs_statusupdates_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/runs/rdp_rhs_statusupdates_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/runs/taskinbox_spec.js b/e2e-tests/cypress/tests/integration/playbooks/runs/taskinbox_spec.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/runs/taskinbox_spec.js rename to e2e-tests/cypress/tests/integration/playbooks/runs/taskinbox_spec.js diff --git a/e2e/cypress/tests/integration/playbooks/tours_spec_ignore_.js b/e2e-tests/cypress/tests/integration/playbooks/tours_spec_ignore_.js similarity index 100% rename from e2e/cypress/tests/integration/playbooks/tours_spec_ignore_.js rename to e2e-tests/cypress/tests/integration/playbooks/tours_spec_ignore_.js diff --git a/e2e/cypress/tests/plugins/client_request.js b/e2e-tests/cypress/tests/plugins/client_request.js similarity index 100% rename from e2e/cypress/tests/plugins/client_request.js rename to e2e-tests/cypress/tests/plugins/client_request.js diff --git a/e2e/cypress/tests/plugins/db_request.js b/e2e-tests/cypress/tests/plugins/db_request.js similarity index 100% rename from e2e/cypress/tests/plugins/db_request.js rename to e2e-tests/cypress/tests/plugins/db_request.js diff --git a/e2e/cypress/tests/plugins/external_request.ts b/e2e-tests/cypress/tests/plugins/external_request.ts similarity index 100% rename from e2e/cypress/tests/plugins/external_request.ts rename to e2e-tests/cypress/tests/plugins/external_request.ts diff --git a/e2e/cypress/tests/plugins/file_util.js b/e2e-tests/cypress/tests/plugins/file_util.js similarity index 100% rename from e2e/cypress/tests/plugins/file_util.js rename to e2e-tests/cypress/tests/plugins/file_util.js diff --git a/e2e/cypress/tests/plugins/get_pdf_content.js b/e2e-tests/cypress/tests/plugins/get_pdf_content.js similarity index 100% rename from e2e/cypress/tests/plugins/get_pdf_content.js rename to e2e-tests/cypress/tests/plugins/get_pdf_content.js diff --git a/e2e/cypress/tests/plugins/get_recent_email.js b/e2e-tests/cypress/tests/plugins/get_recent_email.js similarity index 100% rename from e2e/cypress/tests/plugins/get_recent_email.js rename to e2e-tests/cypress/tests/plugins/get_recent_email.js diff --git a/e2e/cypress/tests/plugins/index.js b/e2e-tests/cypress/tests/plugins/index.js similarity index 100% rename from e2e/cypress/tests/plugins/index.js rename to e2e-tests/cypress/tests/plugins/index.js diff --git a/e2e/cypress/tests/plugins/keycloak_request.js b/e2e-tests/cypress/tests/plugins/keycloak_request.js similarity index 100% rename from e2e/cypress/tests/plugins/keycloak_request.js rename to e2e-tests/cypress/tests/plugins/keycloak_request.js diff --git a/e2e/cypress/tests/plugins/okta_request.js b/e2e-tests/cypress/tests/plugins/okta_request.js similarity index 100% rename from e2e/cypress/tests/plugins/okta_request.js rename to e2e-tests/cypress/tests/plugins/okta_request.js diff --git a/e2e/cypress/tests/plugins/post_bot_message.js b/e2e-tests/cypress/tests/plugins/post_bot_message.js similarity index 100% rename from e2e/cypress/tests/plugins/post_bot_message.js rename to e2e-tests/cypress/tests/plugins/post_bot_message.js diff --git a/e2e/cypress/tests/plugins/post_incoming_webhook.js b/e2e-tests/cypress/tests/plugins/post_incoming_webhook.js similarity index 100% rename from e2e/cypress/tests/plugins/post_incoming_webhook.js rename to e2e-tests/cypress/tests/plugins/post_incoming_webhook.js diff --git a/e2e/cypress/tests/plugins/post_list_of_messages.js b/e2e-tests/cypress/tests/plugins/post_list_of_messages.js similarity index 100% rename from e2e/cypress/tests/plugins/post_list_of_messages.js rename to e2e-tests/cypress/tests/plugins/post_list_of_messages.js diff --git a/e2e/cypress/tests/plugins/post_message_as.js b/e2e-tests/cypress/tests/plugins/post_message_as.js similarity index 100% rename from e2e/cypress/tests/plugins/post_message_as.js rename to e2e-tests/cypress/tests/plugins/post_message_as.js diff --git a/e2e/cypress/tests/plugins/react_to_message_as.js b/e2e-tests/cypress/tests/plugins/react_to_message_as.js similarity index 100% rename from e2e/cypress/tests/plugins/react_to_message_as.js rename to e2e-tests/cypress/tests/plugins/react_to_message_as.js diff --git a/e2e/cypress/tests/plugins/shell.js b/e2e-tests/cypress/tests/plugins/shell.js similarity index 100% rename from e2e/cypress/tests/plugins/shell.js rename to e2e-tests/cypress/tests/plugins/shell.js diff --git a/e2e/cypress/tests/plugins/url_health_check.js b/e2e-tests/cypress/tests/plugins/url_health_check.js similarity index 100% rename from e2e/cypress/tests/plugins/url_health_check.js rename to e2e-tests/cypress/tests/plugins/url_health_check.js diff --git a/e2e/cypress/tests/support/api/bots.d.ts b/e2e-tests/cypress/tests/support/api/bots.d.ts similarity index 100% rename from e2e/cypress/tests/support/api/bots.d.ts rename to e2e-tests/cypress/tests/support/api/bots.d.ts diff --git a/e2e/cypress/tests/support/api/bots.js b/e2e-tests/cypress/tests/support/api/bots.js similarity index 100% rename from e2e/cypress/tests/support/api/bots.js rename to e2e-tests/cypress/tests/support/api/bots.js diff --git a/e2e/cypress/tests/support/api/brand.d.ts b/e2e-tests/cypress/tests/support/api/brand.d.ts similarity index 100% rename from e2e/cypress/tests/support/api/brand.d.ts rename to e2e-tests/cypress/tests/support/api/brand.d.ts diff --git a/e2e/cypress/tests/support/api/brand.js b/e2e-tests/cypress/tests/support/api/brand.js similarity index 100% rename from e2e/cypress/tests/support/api/brand.js rename to e2e-tests/cypress/tests/support/api/brand.js diff --git a/e2e/cypress/tests/support/api/channel.d.ts b/e2e-tests/cypress/tests/support/api/channel.d.ts similarity index 100% rename from e2e/cypress/tests/support/api/channel.d.ts rename to e2e-tests/cypress/tests/support/api/channel.d.ts diff --git a/e2e/cypress/tests/support/api/channel.js b/e2e-tests/cypress/tests/support/api/channel.js similarity index 100% rename from e2e/cypress/tests/support/api/channel.js rename to e2e-tests/cypress/tests/support/api/channel.js diff --git a/e2e/cypress/tests/support/api/cloud.d.ts b/e2e-tests/cypress/tests/support/api/cloud.d.ts similarity index 100% rename from e2e/cypress/tests/support/api/cloud.d.ts rename to e2e-tests/cypress/tests/support/api/cloud.d.ts diff --git a/e2e/cypress/tests/support/api/cloud.js b/e2e-tests/cypress/tests/support/api/cloud.js similarity index 100% rename from e2e/cypress/tests/support/api/cloud.js rename to e2e-tests/cypress/tests/support/api/cloud.js diff --git a/e2e/cypress/tests/support/api/cloud_default_config.json b/e2e-tests/cypress/tests/support/api/cloud_default_config.json similarity index 100% rename from e2e/cypress/tests/support/api/cloud_default_config.json rename to e2e-tests/cypress/tests/support/api/cloud_default_config.json diff --git a/e2e/cypress/tests/support/api/cluster.d.ts b/e2e-tests/cypress/tests/support/api/cluster.d.ts similarity index 100% rename from e2e/cypress/tests/support/api/cluster.d.ts rename to e2e-tests/cypress/tests/support/api/cluster.d.ts diff --git a/e2e/cypress/tests/support/api/cluster.js b/e2e-tests/cypress/tests/support/api/cluster.js similarity index 100% rename from e2e/cypress/tests/support/api/cluster.js rename to e2e-tests/cypress/tests/support/api/cluster.js diff --git a/e2e/cypress/tests/support/api/common.d.ts b/e2e-tests/cypress/tests/support/api/common.d.ts similarity index 100% rename from e2e/cypress/tests/support/api/common.d.ts rename to e2e-tests/cypress/tests/support/api/common.d.ts diff --git a/e2e/cypress/tests/support/api/common.js b/e2e-tests/cypress/tests/support/api/common.js similarity index 100% rename from e2e/cypress/tests/support/api/common.js rename to e2e-tests/cypress/tests/support/api/common.js diff --git a/e2e/cypress/tests/support/api/data_retention.d.ts b/e2e-tests/cypress/tests/support/api/data_retention.d.ts similarity index 100% rename from e2e/cypress/tests/support/api/data_retention.d.ts rename to e2e-tests/cypress/tests/support/api/data_retention.d.ts diff --git a/e2e/cypress/tests/support/api/data_retention.js b/e2e-tests/cypress/tests/support/api/data_retention.js similarity index 100% rename from e2e/cypress/tests/support/api/data_retention.js rename to e2e-tests/cypress/tests/support/api/data_retention.js diff --git a/e2e/cypress/tests/support/api/helpers.js b/e2e-tests/cypress/tests/support/api/helpers.js similarity index 100% rename from e2e/cypress/tests/support/api/helpers.js rename to e2e-tests/cypress/tests/support/api/helpers.js diff --git a/e2e/cypress/tests/support/api/index.js b/e2e-tests/cypress/tests/support/api/index.js similarity index 100% rename from e2e/cypress/tests/support/api/index.js rename to e2e-tests/cypress/tests/support/api/index.js diff --git a/e2e/cypress/tests/support/api/keycloak.d.ts b/e2e-tests/cypress/tests/support/api/keycloak.d.ts similarity index 100% rename from e2e/cypress/tests/support/api/keycloak.d.ts rename to e2e-tests/cypress/tests/support/api/keycloak.d.ts diff --git a/e2e/cypress/tests/support/api/keycloak.js b/e2e-tests/cypress/tests/support/api/keycloak.js similarity index 100% rename from e2e/cypress/tests/support/api/keycloak.js rename to e2e-tests/cypress/tests/support/api/keycloak.js diff --git a/e2e/cypress/tests/support/api/keycloak_realm.json b/e2e-tests/cypress/tests/support/api/keycloak_realm.json similarity index 100% rename from e2e/cypress/tests/support/api/keycloak_realm.json rename to e2e-tests/cypress/tests/support/api/keycloak_realm.json diff --git a/e2e/cypress/tests/support/api/ldap.d.ts b/e2e-tests/cypress/tests/support/api/ldap.d.ts similarity index 100% rename from e2e/cypress/tests/support/api/ldap.d.ts rename to e2e-tests/cypress/tests/support/api/ldap.d.ts diff --git a/e2e/cypress/tests/support/api/ldap.js b/e2e-tests/cypress/tests/support/api/ldap.js similarity index 100% rename from e2e/cypress/tests/support/api/ldap.js rename to e2e-tests/cypress/tests/support/api/ldap.js diff --git a/e2e/cypress/tests/support/api/on_prem_default_config.json b/e2e-tests/cypress/tests/support/api/on_prem_default_config.json similarity index 100% rename from e2e/cypress/tests/support/api/on_prem_default_config.json rename to e2e-tests/cypress/tests/support/api/on_prem_default_config.json diff --git a/e2e/cypress/tests/support/api/playbooks.js b/e2e-tests/cypress/tests/support/api/playbooks.js similarity index 100% rename from e2e/cypress/tests/support/api/playbooks.js rename to e2e-tests/cypress/tests/support/api/playbooks.js diff --git a/e2e/cypress/tests/support/api/plugin.d.ts b/e2e-tests/cypress/tests/support/api/plugin.d.ts similarity index 100% rename from e2e/cypress/tests/support/api/plugin.d.ts rename to e2e-tests/cypress/tests/support/api/plugin.d.ts diff --git a/e2e/cypress/tests/support/api/plugin.js b/e2e-tests/cypress/tests/support/api/plugin.js similarity index 100% rename from e2e/cypress/tests/support/api/plugin.js rename to e2e-tests/cypress/tests/support/api/plugin.js diff --git a/e2e/cypress/tests/support/api/preference.d.ts b/e2e-tests/cypress/tests/support/api/preference.d.ts similarity index 100% rename from e2e/cypress/tests/support/api/preference.d.ts rename to e2e-tests/cypress/tests/support/api/preference.d.ts diff --git a/e2e/cypress/tests/support/api/preference.js b/e2e-tests/cypress/tests/support/api/preference.js similarity index 100% rename from e2e/cypress/tests/support/api/preference.js rename to e2e-tests/cypress/tests/support/api/preference.js diff --git a/e2e/cypress/tests/support/api/role.d.ts b/e2e-tests/cypress/tests/support/api/role.d.ts similarity index 100% rename from e2e/cypress/tests/support/api/role.d.ts rename to e2e-tests/cypress/tests/support/api/role.d.ts diff --git a/e2e/cypress/tests/support/api/role.js b/e2e-tests/cypress/tests/support/api/role.js similarity index 100% rename from e2e/cypress/tests/support/api/role.js rename to e2e-tests/cypress/tests/support/api/role.js diff --git a/e2e/cypress/tests/support/api/saml.d.ts b/e2e-tests/cypress/tests/support/api/saml.d.ts similarity index 100% rename from e2e/cypress/tests/support/api/saml.d.ts rename to e2e-tests/cypress/tests/support/api/saml.d.ts diff --git a/e2e/cypress/tests/support/api/saml.js b/e2e-tests/cypress/tests/support/api/saml.js similarity index 100% rename from e2e/cypress/tests/support/api/saml.js rename to e2e-tests/cypress/tests/support/api/saml.js diff --git a/e2e/cypress/tests/support/api/scheme.d.ts b/e2e-tests/cypress/tests/support/api/scheme.d.ts similarity index 100% rename from e2e/cypress/tests/support/api/scheme.d.ts rename to e2e-tests/cypress/tests/support/api/scheme.d.ts diff --git a/e2e/cypress/tests/support/api/scheme.js b/e2e-tests/cypress/tests/support/api/scheme.js similarity index 100% rename from e2e/cypress/tests/support/api/scheme.js rename to e2e-tests/cypress/tests/support/api/scheme.js diff --git a/e2e/cypress/tests/support/api/setup.ts b/e2e-tests/cypress/tests/support/api/setup.ts similarity index 100% rename from e2e/cypress/tests/support/api/setup.ts rename to e2e-tests/cypress/tests/support/api/setup.ts diff --git a/e2e/cypress/tests/support/api/status.d.ts b/e2e-tests/cypress/tests/support/api/status.d.ts similarity index 100% rename from e2e/cypress/tests/support/api/status.d.ts rename to e2e-tests/cypress/tests/support/api/status.d.ts diff --git a/e2e/cypress/tests/support/api/status.js b/e2e-tests/cypress/tests/support/api/status.js similarity index 100% rename from e2e/cypress/tests/support/api/status.js rename to e2e-tests/cypress/tests/support/api/status.js diff --git a/e2e/cypress/tests/support/api/system.d.ts b/e2e-tests/cypress/tests/support/api/system.d.ts similarity index 100% rename from e2e/cypress/tests/support/api/system.d.ts rename to e2e-tests/cypress/tests/support/api/system.d.ts diff --git a/e2e/cypress/tests/support/api/system.js b/e2e-tests/cypress/tests/support/api/system.js similarity index 100% rename from e2e/cypress/tests/support/api/system.js rename to e2e-tests/cypress/tests/support/api/system.js diff --git a/e2e/cypress/tests/support/api/team.d.ts b/e2e-tests/cypress/tests/support/api/team.d.ts similarity index 100% rename from e2e/cypress/tests/support/api/team.d.ts rename to e2e-tests/cypress/tests/support/api/team.d.ts diff --git a/e2e/cypress/tests/support/api/team.js b/e2e-tests/cypress/tests/support/api/team.js similarity index 100% rename from e2e/cypress/tests/support/api/team.js rename to e2e-tests/cypress/tests/support/api/team.js diff --git a/e2e/cypress/tests/support/api/user.d.ts b/e2e-tests/cypress/tests/support/api/user.d.ts similarity index 100% rename from e2e/cypress/tests/support/api/user.d.ts rename to e2e-tests/cypress/tests/support/api/user.d.ts diff --git a/e2e/cypress/tests/support/api/user.js b/e2e-tests/cypress/tests/support/api/user.js similarity index 100% rename from e2e/cypress/tests/support/api/user.js rename to e2e-tests/cypress/tests/support/api/user.js diff --git a/e2e/cypress/tests/support/api/webhooks.d.ts b/e2e-tests/cypress/tests/support/api/webhooks.d.ts similarity index 100% rename from e2e/cypress/tests/support/api/webhooks.d.ts rename to e2e-tests/cypress/tests/support/api/webhooks.d.ts diff --git a/e2e/cypress/tests/support/api/webhooks.js b/e2e-tests/cypress/tests/support/api/webhooks.js similarity index 100% rename from e2e/cypress/tests/support/api/webhooks.js rename to e2e-tests/cypress/tests/support/api/webhooks.js diff --git a/e2e/cypress/tests/support/api_commands.ts b/e2e-tests/cypress/tests/support/api_commands.ts similarity index 100% rename from e2e/cypress/tests/support/api_commands.ts rename to e2e-tests/cypress/tests/support/api_commands.ts diff --git a/e2e/cypress/tests/support/assertions.js b/e2e-tests/cypress/tests/support/assertions.js similarity index 100% rename from e2e/cypress/tests/support/assertions.js rename to e2e-tests/cypress/tests/support/assertions.js diff --git a/e2e/cypress/tests/support/client-impl.js b/e2e-tests/cypress/tests/support/client-impl.js similarity index 100% rename from e2e/cypress/tests/support/client-impl.js rename to e2e-tests/cypress/tests/support/client-impl.js diff --git a/e2e/cypress/tests/support/client.d.ts b/e2e-tests/cypress/tests/support/client.d.ts similarity index 100% rename from e2e/cypress/tests/support/client.d.ts rename to e2e-tests/cypress/tests/support/client.d.ts diff --git a/e2e/cypress/tests/support/client.js b/e2e-tests/cypress/tests/support/client.js similarity index 100% rename from e2e/cypress/tests/support/client.js rename to e2e-tests/cypress/tests/support/client.js diff --git a/e2e/cypress/tests/support/common_login_commands.d.ts b/e2e-tests/cypress/tests/support/common_login_commands.d.ts similarity index 100% rename from e2e/cypress/tests/support/common_login_commands.d.ts rename to e2e-tests/cypress/tests/support/common_login_commands.d.ts diff --git a/e2e/cypress/tests/support/common_login_commands.js b/e2e-tests/cypress/tests/support/common_login_commands.js similarity index 100% rename from e2e/cypress/tests/support/common_login_commands.js rename to e2e-tests/cypress/tests/support/common_login_commands.js diff --git a/e2e/cypress/tests/support/constants.js b/e2e-tests/cypress/tests/support/constants.js similarity index 100% rename from e2e/cypress/tests/support/constants.js rename to e2e-tests/cypress/tests/support/constants.js diff --git a/e2e/cypress/tests/support/db_commands.ts b/e2e-tests/cypress/tests/support/db_commands.ts similarity index 100% rename from e2e/cypress/tests/support/db_commands.ts rename to e2e-tests/cypress/tests/support/db_commands.ts diff --git a/e2e/cypress/tests/support/email.ts b/e2e-tests/cypress/tests/support/email.ts similarity index 100% rename from e2e/cypress/tests/support/email.ts rename to e2e-tests/cypress/tests/support/email.ts diff --git a/e2e/cypress/tests/support/env.ts b/e2e-tests/cypress/tests/support/env.ts similarity index 100% rename from e2e/cypress/tests/support/env.ts rename to e2e-tests/cypress/tests/support/env.ts diff --git a/e2e/cypress/tests/support/extended_commands.d.ts b/e2e-tests/cypress/tests/support/extended_commands.d.ts similarity index 100% rename from e2e/cypress/tests/support/extended_commands.d.ts rename to e2e-tests/cypress/tests/support/extended_commands.d.ts diff --git a/e2e/cypress/tests/support/extended_commands.js b/e2e-tests/cypress/tests/support/extended_commands.js similarity index 100% rename from e2e/cypress/tests/support/extended_commands.js rename to e2e-tests/cypress/tests/support/extended_commands.js diff --git a/e2e/cypress/tests/support/external_commands.d.ts b/e2e-tests/cypress/tests/support/external_commands.d.ts similarity index 100% rename from e2e/cypress/tests/support/external_commands.d.ts rename to e2e-tests/cypress/tests/support/external_commands.d.ts diff --git a/e2e/cypress/tests/support/external_commands.js b/e2e-tests/cypress/tests/support/external_commands.js similarity index 100% rename from e2e/cypress/tests/support/external_commands.js rename to e2e-tests/cypress/tests/support/external_commands.js diff --git a/e2e/cypress/tests/support/fetch_commands.js b/e2e-tests/cypress/tests/support/fetch_commands.js similarity index 100% rename from e2e/cypress/tests/support/fetch_commands.js rename to e2e-tests/cypress/tests/support/fetch_commands.js diff --git a/e2e/cypress/tests/support/index.d.ts b/e2e-tests/cypress/tests/support/index.d.ts similarity index 100% rename from e2e/cypress/tests/support/index.d.ts rename to e2e-tests/cypress/tests/support/index.d.ts diff --git a/e2e/cypress/tests/support/index.js b/e2e-tests/cypress/tests/support/index.js similarity index 100% rename from e2e/cypress/tests/support/index.js rename to e2e-tests/cypress/tests/support/index.js diff --git a/e2e/cypress/tests/support/keycloak_commands.d.ts b/e2e-tests/cypress/tests/support/keycloak_commands.d.ts similarity index 100% rename from e2e/cypress/tests/support/keycloak_commands.d.ts rename to e2e-tests/cypress/tests/support/keycloak_commands.d.ts diff --git a/e2e/cypress/tests/support/keycloak_commands.js b/e2e-tests/cypress/tests/support/keycloak_commands.js similarity index 100% rename from e2e/cypress/tests/support/keycloak_commands.js rename to e2e-tests/cypress/tests/support/keycloak_commands.js diff --git a/e2e/cypress/tests/support/ldap_commands.d.ts b/e2e-tests/cypress/tests/support/ldap_commands.d.ts similarity index 100% rename from e2e/cypress/tests/support/ldap_commands.d.ts rename to e2e-tests/cypress/tests/support/ldap_commands.d.ts diff --git a/e2e/cypress/tests/support/ldap_commands.js b/e2e-tests/cypress/tests/support/ldap_commands.js similarity index 100% rename from e2e/cypress/tests/support/ldap_commands.js rename to e2e-tests/cypress/tests/support/ldap_commands.js diff --git a/e2e/cypress/tests/support/ldap_server_commands.d.ts b/e2e-tests/cypress/tests/support/ldap_server_commands.d.ts similarity index 100% rename from e2e/cypress/tests/support/ldap_server_commands.d.ts rename to e2e-tests/cypress/tests/support/ldap_server_commands.d.ts diff --git a/e2e/cypress/tests/support/ldap_server_commands.js b/e2e-tests/cypress/tests/support/ldap_server_commands.js similarity index 100% rename from e2e/cypress/tests/support/ldap_server_commands.js rename to e2e-tests/cypress/tests/support/ldap_server_commands.js diff --git a/e2e/cypress/tests/support/notification.ts b/e2e-tests/cypress/tests/support/notification.ts similarity index 100% rename from e2e/cypress/tests/support/notification.ts rename to e2e-tests/cypress/tests/support/notification.ts diff --git a/e2e/cypress/tests/support/okta_commands.js b/e2e-tests/cypress/tests/support/okta_commands.js similarity index 100% rename from e2e/cypress/tests/support/okta_commands.js rename to e2e-tests/cypress/tests/support/okta_commands.js diff --git a/e2e/cypress/tests/support/saml_commands.js b/e2e-tests/cypress/tests/support/saml_commands.js similarity index 100% rename from e2e/cypress/tests/support/saml_commands.js rename to e2e-tests/cypress/tests/support/saml_commands.js diff --git a/e2e/cypress/tests/support/shell.d.ts b/e2e-tests/cypress/tests/support/shell.d.ts similarity index 100% rename from e2e/cypress/tests/support/shell.d.ts rename to e2e-tests/cypress/tests/support/shell.d.ts diff --git a/e2e/cypress/tests/support/shell.js b/e2e-tests/cypress/tests/support/shell.js similarity index 100% rename from e2e/cypress/tests/support/shell.js rename to e2e-tests/cypress/tests/support/shell.js diff --git a/e2e/cypress/tests/support/task_commands.ts b/e2e-tests/cypress/tests/support/task_commands.ts similarity index 100% rename from e2e/cypress/tests/support/task_commands.ts rename to e2e-tests/cypress/tests/support/task_commands.ts diff --git a/e2e/cypress/tests/support/ui/account_settings_modal.d.ts b/e2e-tests/cypress/tests/support/ui/account_settings_modal.d.ts similarity index 100% rename from e2e/cypress/tests/support/ui/account_settings_modal.d.ts rename to e2e-tests/cypress/tests/support/ui/account_settings_modal.d.ts diff --git a/e2e/cypress/tests/support/ui/account_settings_modal.js b/e2e-tests/cypress/tests/support/ui/account_settings_modal.js similarity index 100% rename from e2e/cypress/tests/support/ui/account_settings_modal.js rename to e2e-tests/cypress/tests/support/ui/account_settings_modal.js diff --git a/e2e/cypress/tests/support/ui/announcement_bar.d.ts b/e2e-tests/cypress/tests/support/ui/announcement_bar.d.ts similarity index 100% rename from e2e/cypress/tests/support/ui/announcement_bar.d.ts rename to e2e-tests/cypress/tests/support/ui/announcement_bar.d.ts diff --git a/e2e/cypress/tests/support/ui/announcement_bar.js b/e2e-tests/cypress/tests/support/ui/announcement_bar.js similarity index 100% rename from e2e/cypress/tests/support/ui/announcement_bar.js rename to e2e-tests/cypress/tests/support/ui/announcement_bar.js diff --git a/e2e/cypress/tests/support/ui/boards.d.ts b/e2e-tests/cypress/tests/support/ui/boards.d.ts similarity index 100% rename from e2e/cypress/tests/support/ui/boards.d.ts rename to e2e-tests/cypress/tests/support/ui/boards.d.ts diff --git a/e2e/cypress/tests/support/ui/boards.js b/e2e-tests/cypress/tests/support/ui/boards.js similarity index 100% rename from e2e/cypress/tests/support/ui/boards.js rename to e2e-tests/cypress/tests/support/ui/boards.js diff --git a/e2e/cypress/tests/support/ui/channel.d.ts b/e2e-tests/cypress/tests/support/ui/channel.d.ts similarity index 100% rename from e2e/cypress/tests/support/ui/channel.d.ts rename to e2e-tests/cypress/tests/support/ui/channel.d.ts diff --git a/e2e/cypress/tests/support/ui/channel.js b/e2e-tests/cypress/tests/support/ui/channel.js similarity index 100% rename from e2e/cypress/tests/support/ui/channel.js rename to e2e-tests/cypress/tests/support/ui/channel.js diff --git a/e2e/cypress/tests/support/ui/channel_header.d.ts b/e2e-tests/cypress/tests/support/ui/channel_header.d.ts similarity index 100% rename from e2e/cypress/tests/support/ui/channel_header.d.ts rename to e2e-tests/cypress/tests/support/ui/channel_header.d.ts diff --git a/e2e/cypress/tests/support/ui/channel_header.js b/e2e-tests/cypress/tests/support/ui/channel_header.js similarity index 100% rename from e2e/cypress/tests/support/ui/channel_header.js rename to e2e-tests/cypress/tests/support/ui/channel_header.js diff --git a/e2e/cypress/tests/support/ui/channel_sidebar.js b/e2e-tests/cypress/tests/support/ui/channel_sidebar.js similarity index 100% rename from e2e/cypress/tests/support/ui/channel_sidebar.js rename to e2e-tests/cypress/tests/support/ui/channel_sidebar.js diff --git a/e2e/cypress/tests/support/ui/cloud_billing.d.ts b/e2e-tests/cypress/tests/support/ui/cloud_billing.d.ts similarity index 100% rename from e2e/cypress/tests/support/ui/cloud_billing.d.ts rename to e2e-tests/cypress/tests/support/ui/cloud_billing.d.ts diff --git a/e2e/cypress/tests/support/ui/cloud_billing.js b/e2e-tests/cypress/tests/support/ui/cloud_billing.js similarity index 100% rename from e2e/cypress/tests/support/ui/cloud_billing.js rename to e2e-tests/cypress/tests/support/ui/cloud_billing.js diff --git a/e2e/cypress/tests/support/ui/common.d.ts b/e2e-tests/cypress/tests/support/ui/common.d.ts similarity index 100% rename from e2e/cypress/tests/support/ui/common.d.ts rename to e2e-tests/cypress/tests/support/ui/common.d.ts diff --git a/e2e/cypress/tests/support/ui/common.js b/e2e-tests/cypress/tests/support/ui/common.js similarity index 100% rename from e2e/cypress/tests/support/ui/common.js rename to e2e-tests/cypress/tests/support/ui/common.js diff --git a/e2e/cypress/tests/support/ui/compliance_export.d.ts b/e2e-tests/cypress/tests/support/ui/compliance_export.d.ts similarity index 100% rename from e2e/cypress/tests/support/ui/compliance_export.d.ts rename to e2e-tests/cypress/tests/support/ui/compliance_export.d.ts diff --git a/e2e/cypress/tests/support/ui/compliance_export.js b/e2e-tests/cypress/tests/support/ui/compliance_export.js similarity index 100% rename from e2e/cypress/tests/support/ui/compliance_export.js rename to e2e-tests/cypress/tests/support/ui/compliance_export.js diff --git a/e2e/cypress/tests/support/ui/data_retention.d.ts b/e2e-tests/cypress/tests/support/ui/data_retention.d.ts similarity index 100% rename from e2e/cypress/tests/support/ui/data_retention.d.ts rename to e2e-tests/cypress/tests/support/ui/data_retention.d.ts diff --git a/e2e/cypress/tests/support/ui/data_retention.js b/e2e-tests/cypress/tests/support/ui/data_retention.js similarity index 100% rename from e2e/cypress/tests/support/ui/data_retention.js rename to e2e-tests/cypress/tests/support/ui/data_retention.js diff --git a/e2e/cypress/tests/support/ui/emoji.ts b/e2e-tests/cypress/tests/support/ui/emoji.ts similarity index 100% rename from e2e/cypress/tests/support/ui/emoji.ts rename to e2e-tests/cypress/tests/support/ui/emoji.ts diff --git a/e2e/cypress/tests/support/ui/extend_testing_library.d.ts b/e2e-tests/cypress/tests/support/ui/extend_testing_library.d.ts similarity index 100% rename from e2e/cypress/tests/support/ui/extend_testing_library.d.ts rename to e2e-tests/cypress/tests/support/ui/extend_testing_library.d.ts diff --git a/e2e/cypress/tests/support/ui/extend_testing_library.js b/e2e-tests/cypress/tests/support/ui/extend_testing_library.js similarity index 100% rename from e2e/cypress/tests/support/ui/extend_testing_library.js rename to e2e-tests/cypress/tests/support/ui/extend_testing_library.js diff --git a/e2e/cypress/tests/support/ui/file_preview.d.ts b/e2e-tests/cypress/tests/support/ui/file_preview.d.ts similarity index 100% rename from e2e/cypress/tests/support/ui/file_preview.d.ts rename to e2e-tests/cypress/tests/support/ui/file_preview.d.ts diff --git a/e2e/cypress/tests/support/ui/file_preview.js b/e2e-tests/cypress/tests/support/ui/file_preview.js similarity index 100% rename from e2e/cypress/tests/support/ui/file_preview.js rename to e2e-tests/cypress/tests/support/ui/file_preview.js diff --git a/e2e/cypress/tests/support/ui/global_header.d.ts b/e2e-tests/cypress/tests/support/ui/global_header.d.ts similarity index 100% rename from e2e/cypress/tests/support/ui/global_header.d.ts rename to e2e-tests/cypress/tests/support/ui/global_header.d.ts diff --git a/e2e/cypress/tests/support/ui/global_header.js b/e2e-tests/cypress/tests/support/ui/global_header.js similarity index 100% rename from e2e/cypress/tests/support/ui/global_header.js rename to e2e-tests/cypress/tests/support/ui/global_header.js diff --git a/e2e/cypress/tests/support/ui/index.js b/e2e-tests/cypress/tests/support/ui/index.js similarity index 100% rename from e2e/cypress/tests/support/ui/index.js rename to e2e-tests/cypress/tests/support/ui/index.js diff --git a/e2e/cypress/tests/support/ui/login.d.ts b/e2e-tests/cypress/tests/support/ui/login.d.ts similarity index 100% rename from e2e/cypress/tests/support/ui/login.d.ts rename to e2e-tests/cypress/tests/support/ui/login.d.ts diff --git a/e2e/cypress/tests/support/ui/login.js b/e2e-tests/cypress/tests/support/ui/login.js similarity index 100% rename from e2e/cypress/tests/support/ui/login.js rename to e2e-tests/cypress/tests/support/ui/login.js diff --git a/e2e/cypress/tests/support/ui/menu.d.ts b/e2e-tests/cypress/tests/support/ui/menu.d.ts similarity index 100% rename from e2e/cypress/tests/support/ui/menu.d.ts rename to e2e-tests/cypress/tests/support/ui/menu.d.ts diff --git a/e2e/cypress/tests/support/ui/menu.js b/e2e-tests/cypress/tests/support/ui/menu.js similarity index 100% rename from e2e/cypress/tests/support/ui/menu.js rename to e2e-tests/cypress/tests/support/ui/menu.js diff --git a/e2e/cypress/tests/support/ui/mfa.d.ts b/e2e-tests/cypress/tests/support/ui/mfa.d.ts similarity index 100% rename from e2e/cypress/tests/support/ui/mfa.d.ts rename to e2e-tests/cypress/tests/support/ui/mfa.d.ts diff --git a/e2e/cypress/tests/support/ui/mfa.js b/e2e-tests/cypress/tests/support/ui/mfa.js similarity index 100% rename from e2e/cypress/tests/support/ui/mfa.js rename to e2e-tests/cypress/tests/support/ui/mfa.js diff --git a/e2e/cypress/tests/support/ui/modal.d.ts b/e2e-tests/cypress/tests/support/ui/modal.d.ts similarity index 100% rename from e2e/cypress/tests/support/ui/modal.d.ts rename to e2e-tests/cypress/tests/support/ui/modal.d.ts diff --git a/e2e/cypress/tests/support/ui/modal.js b/e2e-tests/cypress/tests/support/ui/modal.js similarity index 100% rename from e2e/cypress/tests/support/ui/modal.js rename to e2e-tests/cypress/tests/support/ui/modal.js diff --git a/e2e/cypress/tests/support/ui/playbooks.js b/e2e-tests/cypress/tests/support/ui/playbooks.js similarity index 100% rename from e2e/cypress/tests/support/ui/playbooks.js rename to e2e-tests/cypress/tests/support/ui/playbooks.js diff --git a/e2e/cypress/tests/support/ui/post.ts b/e2e-tests/cypress/tests/support/ui/post.ts similarity index 100% rename from e2e/cypress/tests/support/ui/post.ts rename to e2e-tests/cypress/tests/support/ui/post.ts diff --git a/e2e/cypress/tests/support/ui/post_dropdown_menu.d.ts b/e2e-tests/cypress/tests/support/ui/post_dropdown_menu.d.ts similarity index 100% rename from e2e/cypress/tests/support/ui/post_dropdown_menu.d.ts rename to e2e-tests/cypress/tests/support/ui/post_dropdown_menu.d.ts diff --git a/e2e/cypress/tests/support/ui/post_dropdown_menu.js b/e2e-tests/cypress/tests/support/ui/post_dropdown_menu.js similarity index 100% rename from e2e/cypress/tests/support/ui/post_dropdown_menu.js rename to e2e-tests/cypress/tests/support/ui/post_dropdown_menu.js diff --git a/e2e/cypress/tests/support/ui/search.js b/e2e-tests/cypress/tests/support/ui/search.js similarity index 100% rename from e2e/cypress/tests/support/ui/search.js rename to e2e-tests/cypress/tests/support/ui/search.js diff --git a/e2e/cypress/tests/support/ui/sidebar_left.ts b/e2e-tests/cypress/tests/support/ui/sidebar_left.ts similarity index 100% rename from e2e/cypress/tests/support/ui/sidebar_left.ts rename to e2e-tests/cypress/tests/support/ui/sidebar_left.ts diff --git a/e2e/cypress/tests/support/ui/sidebar_right.d.ts b/e2e-tests/cypress/tests/support/ui/sidebar_right.d.ts similarity index 100% rename from e2e/cypress/tests/support/ui/sidebar_right.d.ts rename to e2e-tests/cypress/tests/support/ui/sidebar_right.d.ts diff --git a/e2e/cypress/tests/support/ui/sidebar_right.js b/e2e-tests/cypress/tests/support/ui/sidebar_right.js similarity index 100% rename from e2e/cypress/tests/support/ui/sidebar_right.js rename to e2e-tests/cypress/tests/support/ui/sidebar_right.js diff --git a/e2e/cypress/tests/support/ui/suggestion_list.d.ts b/e2e-tests/cypress/tests/support/ui/suggestion_list.d.ts similarity index 100% rename from e2e/cypress/tests/support/ui/suggestion_list.d.ts rename to e2e-tests/cypress/tests/support/ui/suggestion_list.d.ts diff --git a/e2e/cypress/tests/support/ui/suggestion_list.js b/e2e-tests/cypress/tests/support/ui/suggestion_list.js similarity index 100% rename from e2e/cypress/tests/support/ui/suggestion_list.js rename to e2e-tests/cypress/tests/support/ui/suggestion_list.js diff --git a/e2e/cypress/tests/support/ui/system.d.ts b/e2e-tests/cypress/tests/support/ui/system.d.ts similarity index 100% rename from e2e/cypress/tests/support/ui/system.d.ts rename to e2e-tests/cypress/tests/support/ui/system.d.ts diff --git a/e2e/cypress/tests/support/ui/system.js b/e2e-tests/cypress/tests/support/ui/system.js similarity index 100% rename from e2e/cypress/tests/support/ui/system.js rename to e2e-tests/cypress/tests/support/ui/system.js diff --git a/e2e/cypress/tests/support/ui/team.js b/e2e-tests/cypress/tests/support/ui/team.js similarity index 100% rename from e2e/cypress/tests/support/ui/team.js rename to e2e-tests/cypress/tests/support/ui/team.js diff --git a/e2e/cypress/tests/support/ui/tooltip.d.ts b/e2e-tests/cypress/tests/support/ui/tooltip.d.ts similarity index 100% rename from e2e/cypress/tests/support/ui/tooltip.d.ts rename to e2e-tests/cypress/tests/support/ui/tooltip.d.ts diff --git a/e2e/cypress/tests/support/ui/tooltip.js b/e2e-tests/cypress/tests/support/ui/tooltip.js similarity index 100% rename from e2e/cypress/tests/support/ui/tooltip.js rename to e2e-tests/cypress/tests/support/ui/tooltip.js diff --git a/e2e/cypress/tests/support/ui_commands.ts b/e2e-tests/cypress/tests/support/ui_commands.ts similarity index 100% rename from e2e/cypress/tests/support/ui_commands.ts rename to e2e-tests/cypress/tests/support/ui_commands.ts diff --git a/e2e/cypress/tests/support/win.d.ts b/e2e-tests/cypress/tests/support/win.d.ts similarity index 100% rename from e2e/cypress/tests/support/win.d.ts rename to e2e-tests/cypress/tests/support/win.d.ts diff --git a/e2e/cypress/tests/types/index.ts b/e2e-tests/cypress/tests/types/index.ts similarity index 100% rename from e2e/cypress/tests/types/index.ts rename to e2e-tests/cypress/tests/types/index.ts diff --git a/e2e/cypress/tests/utils/admin_console.js b/e2e-tests/cypress/tests/utils/admin_console.js similarity index 100% rename from e2e/cypress/tests/utils/admin_console.js rename to e2e-tests/cypress/tests/utils/admin_console.js diff --git a/e2e/cypress/tests/utils/benchmark.js b/e2e-tests/cypress/tests/utils/benchmark.js similarity index 100% rename from e2e/cypress/tests/utils/benchmark.js rename to e2e-tests/cypress/tests/utils/benchmark.js diff --git a/e2e/cypress/tests/utils/config.js b/e2e-tests/cypress/tests/utils/config.js similarity index 100% rename from e2e/cypress/tests/utils/config.js rename to e2e-tests/cypress/tests/utils/config.js diff --git a/e2e/cypress/tests/utils/constants.js b/e2e-tests/cypress/tests/utils/constants.js similarity index 100% rename from e2e/cypress/tests/utils/constants.js rename to e2e-tests/cypress/tests/utils/constants.js diff --git a/e2e/cypress/tests/utils/email.js b/e2e-tests/cypress/tests/utils/email.js similarity index 100% rename from e2e/cypress/tests/utils/email.js rename to e2e-tests/cypress/tests/utils/email.js diff --git a/e2e/cypress/tests/utils/file.js b/e2e-tests/cypress/tests/utils/file.js similarity index 100% rename from e2e/cypress/tests/utils/file.js rename to e2e-tests/cypress/tests/utils/file.js diff --git a/e2e/cypress/tests/utils/index.js b/e2e-tests/cypress/tests/utils/index.js similarity index 100% rename from e2e/cypress/tests/utils/index.js rename to e2e-tests/cypress/tests/utils/index.js diff --git a/e2e/cypress/tests/utils/plugins.js b/e2e-tests/cypress/tests/utils/plugins.js similarity index 100% rename from e2e/cypress/tests/utils/plugins.js rename to e2e-tests/cypress/tests/utils/plugins.js diff --git a/e2e/cypress/tests/utils/timezone.js b/e2e-tests/cypress/tests/utils/timezone.js similarity index 100% rename from e2e/cypress/tests/utils/timezone.js rename to e2e-tests/cypress/tests/utils/timezone.js diff --git a/e2e/cypress/tsconfig.json b/e2e-tests/cypress/tsconfig.json similarity index 100% rename from e2e/cypress/tsconfig.json rename to e2e-tests/cypress/tsconfig.json diff --git a/e2e/cypress/utils/artifacts.js b/e2e-tests/cypress/utils/artifacts.js similarity index 100% rename from e2e/cypress/utils/artifacts.js rename to e2e-tests/cypress/utils/artifacts.js diff --git a/e2e/cypress/utils/constants.js b/e2e-tests/cypress/utils/constants.js similarity index 100% rename from e2e/cypress/utils/constants.js rename to e2e-tests/cypress/utils/constants.js diff --git a/e2e/cypress/utils/dashboard.js b/e2e-tests/cypress/utils/dashboard.js similarity index 100% rename from e2e/cypress/utils/dashboard.js rename to e2e-tests/cypress/utils/dashboard.js diff --git a/e2e/cypress/utils/even_distribution.js b/e2e-tests/cypress/utils/even_distribution.js similarity index 100% rename from e2e/cypress/utils/even_distribution.js rename to e2e-tests/cypress/utils/even_distribution.js diff --git a/e2e/cypress/utils/even_distribution.test.js b/e2e-tests/cypress/utils/even_distribution.test.js similarity index 100% rename from e2e/cypress/utils/even_distribution.test.js rename to e2e-tests/cypress/utils/even_distribution.test.js diff --git a/e2e/cypress/utils/file.js b/e2e-tests/cypress/utils/file.js similarity index 100% rename from e2e/cypress/utils/file.js rename to e2e-tests/cypress/utils/file.js diff --git a/e2e/cypress/utils/report.js b/e2e-tests/cypress/utils/report.js similarity index 100% rename from e2e/cypress/utils/report.js rename to e2e-tests/cypress/utils/report.js diff --git a/e2e/cypress/utils/test_cases.js b/e2e-tests/cypress/utils/test_cases.js similarity index 100% rename from e2e/cypress/utils/test_cases.js rename to e2e-tests/cypress/utils/test_cases.js diff --git a/e2e/cypress/utils/webhook_utils.js b/e2e-tests/cypress/utils/webhook_utils.js similarity index 100% rename from e2e/cypress/utils/webhook_utils.js rename to e2e-tests/cypress/utils/webhook_utils.js diff --git a/e2e/cypress/webhook_serve.js b/e2e-tests/cypress/webhook_serve.js similarity index 100% rename from e2e/cypress/webhook_serve.js rename to e2e-tests/cypress/webhook_serve.js diff --git a/e2e/playwright/.eslintignore b/e2e-tests/playwright/.eslintignore similarity index 100% rename from e2e/playwright/.eslintignore rename to e2e-tests/playwright/.eslintignore diff --git a/e2e/playwright/.eslintrc.json b/e2e-tests/playwright/.eslintrc.json similarity index 100% rename from e2e/playwright/.eslintrc.json rename to e2e-tests/playwright/.eslintrc.json diff --git a/e2e/playwright/.percy.yml b/e2e-tests/playwright/.percy.yml similarity index 100% rename from e2e/playwright/.percy.yml rename to e2e-tests/playwright/.percy.yml diff --git a/e2e/playwright/.prettierignore b/e2e-tests/playwright/.prettierignore similarity index 100% rename from e2e/playwright/.prettierignore rename to e2e-tests/playwright/.prettierignore diff --git a/e2e/playwright/.prettierrc.json b/e2e-tests/playwright/.prettierrc.json similarity index 100% rename from e2e/playwright/.prettierrc.json rename to e2e-tests/playwright/.prettierrc.json diff --git a/e2e/playwright/README.md b/e2e-tests/playwright/README.md similarity index 100% rename from e2e/playwright/README.md rename to e2e-tests/playwright/README.md diff --git a/e2e/playwright/global_setup.ts b/e2e-tests/playwright/global_setup.ts similarity index 100% rename from e2e/playwright/global_setup.ts rename to e2e-tests/playwright/global_setup.ts diff --git a/e2e/playwright/package-lock.json b/e2e-tests/playwright/package-lock.json similarity index 100% rename from e2e/playwright/package-lock.json rename to e2e-tests/playwright/package-lock.json diff --git a/e2e/playwright/package.json b/e2e-tests/playwright/package.json similarity index 100% rename from e2e/playwright/package.json rename to e2e-tests/playwright/package.json diff --git a/e2e/playwright/playwright.config.ts b/e2e-tests/playwright/playwright.config.ts similarity index 100% rename from e2e/playwright/playwright.config.ts rename to e2e-tests/playwright/playwright.config.ts diff --git a/e2e/playwright/sample.env b/e2e-tests/playwright/sample.env similarity index 100% rename from e2e/playwright/sample.env rename to e2e-tests/playwright/sample.env diff --git a/e2e/playwright/support/asset/mattermost-icon_128x128.png b/e2e-tests/playwright/support/asset/mattermost-icon_128x128.png similarity index 100% rename from e2e/playwright/support/asset/mattermost-icon_128x128.png rename to e2e-tests/playwright/support/asset/mattermost-icon_128x128.png diff --git a/e2e/playwright/support/browser_context.ts b/e2e-tests/playwright/support/browser_context.ts similarity index 100% rename from e2e/playwright/support/browser_context.ts rename to e2e-tests/playwright/support/browser_context.ts diff --git a/e2e/playwright/support/constant.ts b/e2e-tests/playwright/support/constant.ts similarity index 100% rename from e2e/playwright/support/constant.ts rename to e2e-tests/playwright/support/constant.ts diff --git a/e2e/playwright/support/flag.ts b/e2e-tests/playwright/support/flag.ts similarity index 100% rename from e2e/playwright/support/flag.ts rename to e2e-tests/playwright/support/flag.ts diff --git a/e2e/playwright/support/server/channel.ts b/e2e-tests/playwright/support/server/channel.ts similarity index 100% rename from e2e/playwright/support/server/channel.ts rename to e2e-tests/playwright/support/server/channel.ts diff --git a/e2e/playwright/support/server/client.ts b/e2e-tests/playwright/support/server/client.ts similarity index 100% rename from e2e/playwright/support/server/client.ts rename to e2e-tests/playwright/support/server/client.ts diff --git a/e2e/playwright/support/server/default_config.ts b/e2e-tests/playwright/support/server/default_config.ts similarity index 100% rename from e2e/playwright/support/server/default_config.ts rename to e2e-tests/playwright/support/server/default_config.ts diff --git a/e2e/playwright/support/server/index.ts b/e2e-tests/playwright/support/server/index.ts similarity index 100% rename from e2e/playwright/support/server/index.ts rename to e2e-tests/playwright/support/server/index.ts diff --git a/e2e/playwright/support/server/init.ts b/e2e-tests/playwright/support/server/init.ts similarity index 100% rename from e2e/playwright/support/server/init.ts rename to e2e-tests/playwright/support/server/init.ts diff --git a/e2e/playwright/support/server/team.ts b/e2e-tests/playwright/support/server/team.ts similarity index 100% rename from e2e/playwright/support/server/team.ts rename to e2e-tests/playwright/support/server/team.ts diff --git a/e2e/playwright/support/server/user.ts b/e2e-tests/playwright/support/server/user.ts similarity index 100% rename from e2e/playwright/support/server/user.ts rename to e2e-tests/playwright/support/server/user.ts diff --git a/e2e/playwright/support/test_action.ts b/e2e-tests/playwright/support/test_action.ts similarity index 100% rename from e2e/playwright/support/test_action.ts rename to e2e-tests/playwright/support/test_action.ts diff --git a/e2e/playwright/support/test_fixture.ts b/e2e-tests/playwright/support/test_fixture.ts similarity index 100% rename from e2e/playwright/support/test_fixture.ts rename to e2e-tests/playwright/support/test_fixture.ts diff --git a/e2e/playwright/support/ui/components/boards/create_modal.ts b/e2e-tests/playwright/support/ui/components/boards/create_modal.ts similarity index 100% rename from e2e/playwright/support/ui/components/boards/create_modal.ts rename to e2e-tests/playwright/support/ui/components/boards/create_modal.ts diff --git a/e2e/playwright/support/ui/components/boards/sidebar.ts b/e2e-tests/playwright/support/ui/components/boards/sidebar.ts similarity index 100% rename from e2e/playwright/support/ui/components/boards/sidebar.ts rename to e2e-tests/playwright/support/ui/components/boards/sidebar.ts diff --git a/e2e/playwright/support/ui/components/channels/app_bar.ts b/e2e-tests/playwright/support/ui/components/channels/app_bar.ts similarity index 100% rename from e2e/playwright/support/ui/components/channels/app_bar.ts rename to e2e-tests/playwright/support/ui/components/channels/app_bar.ts diff --git a/e2e/playwright/support/ui/components/channels/header.ts b/e2e-tests/playwright/support/ui/components/channels/header.ts similarity index 100% rename from e2e/playwright/support/ui/components/channels/header.ts rename to e2e-tests/playwright/support/ui/components/channels/header.ts diff --git a/e2e/playwright/support/ui/components/channels/post.ts b/e2e-tests/playwright/support/ui/components/channels/post.ts similarity index 100% rename from e2e/playwright/support/ui/components/channels/post.ts rename to e2e-tests/playwright/support/ui/components/channels/post.ts diff --git a/e2e/playwright/support/ui/components/channels/post_create.ts b/e2e-tests/playwright/support/ui/components/channels/post_create.ts similarity index 100% rename from e2e/playwright/support/ui/components/channels/post_create.ts rename to e2e-tests/playwright/support/ui/components/channels/post_create.ts diff --git a/e2e/playwright/support/ui/components/channels/sidebar_right.ts b/e2e-tests/playwright/support/ui/components/channels/sidebar_right.ts similarity index 100% rename from e2e/playwright/support/ui/components/channels/sidebar_right.ts rename to e2e-tests/playwright/support/ui/components/channels/sidebar_right.ts diff --git a/e2e/playwright/support/ui/components/global_header.ts b/e2e-tests/playwright/support/ui/components/global_header.ts similarity index 100% rename from e2e/playwright/support/ui/components/global_header.ts rename to e2e-tests/playwright/support/ui/components/global_header.ts diff --git a/e2e/playwright/support/ui/components/index.ts b/e2e-tests/playwright/support/ui/components/index.ts similarity index 100% rename from e2e/playwright/support/ui/components/index.ts rename to e2e-tests/playwright/support/ui/components/index.ts diff --git a/e2e/playwright/support/ui/pages/boards_create.ts b/e2e-tests/playwright/support/ui/pages/boards_create.ts similarity index 100% rename from e2e/playwright/support/ui/pages/boards_create.ts rename to e2e-tests/playwright/support/ui/pages/boards_create.ts diff --git a/e2e/playwright/support/ui/pages/boards_view.ts b/e2e-tests/playwright/support/ui/pages/boards_view.ts similarity index 100% rename from e2e/playwright/support/ui/pages/boards_view.ts rename to e2e-tests/playwright/support/ui/pages/boards_view.ts diff --git a/e2e/playwright/support/ui/pages/channels.ts b/e2e-tests/playwright/support/ui/pages/channels.ts similarity index 100% rename from e2e/playwright/support/ui/pages/channels.ts rename to e2e-tests/playwright/support/ui/pages/channels.ts diff --git a/e2e/playwright/support/ui/pages/index.ts b/e2e-tests/playwright/support/ui/pages/index.ts similarity index 100% rename from e2e/playwright/support/ui/pages/index.ts rename to e2e-tests/playwright/support/ui/pages/index.ts diff --git a/e2e/playwright/support/ui/pages/landing_login.ts b/e2e-tests/playwright/support/ui/pages/landing_login.ts similarity index 100% rename from e2e/playwright/support/ui/pages/landing_login.ts rename to e2e-tests/playwright/support/ui/pages/landing_login.ts diff --git a/e2e/playwright/support/ui/pages/login.ts b/e2e-tests/playwright/support/ui/pages/login.ts similarity index 100% rename from e2e/playwright/support/ui/pages/login.ts rename to e2e-tests/playwright/support/ui/pages/login.ts diff --git a/e2e/playwright/support/ui/pages/signup.ts b/e2e-tests/playwright/support/ui/pages/signup.ts similarity index 100% rename from e2e/playwright/support/ui/pages/signup.ts rename to e2e-tests/playwright/support/ui/pages/signup.ts diff --git a/e2e/playwright/support/util.ts b/e2e-tests/playwright/support/util.ts similarity index 100% rename from e2e/playwright/support/util.ts rename to e2e-tests/playwright/support/util.ts diff --git a/e2e/playwright/support/visual/index.ts b/e2e-tests/playwright/support/visual/index.ts similarity index 100% rename from e2e/playwright/support/visual/index.ts rename to e2e-tests/playwright/support/visual/index.ts diff --git a/e2e/playwright/support/visual/percy.ts b/e2e-tests/playwright/support/visual/percy.ts similarity index 100% rename from e2e/playwright/support/visual/percy.ts rename to e2e-tests/playwright/support/visual/percy.ts diff --git a/e2e/playwright/test.config.ts b/e2e-tests/playwright/test.config.ts similarity index 100% rename from e2e/playwright/test.config.ts rename to e2e-tests/playwright/test.config.ts diff --git a/e2e/playwright/tests/functional/boards/board-creation-and-set-up/create_empty_board.spec.ts b/e2e-tests/playwright/tests/functional/boards/board-creation-and-set-up/create_empty_board.spec.ts similarity index 100% rename from e2e/playwright/tests/functional/boards/board-creation-and-set-up/create_empty_board.spec.ts rename to e2e-tests/playwright/tests/functional/boards/board-creation-and-set-up/create_empty_board.spec.ts diff --git a/e2e/playwright/tests/visual/boards/board_template.spec.ts b/e2e-tests/playwright/tests/visual/boards/board_template.spec.ts similarity index 100% rename from e2e/playwright/tests/visual/boards/board_template.spec.ts rename to e2e-tests/playwright/tests/visual/boards/board_template.spec.ts diff --git a/e2e/playwright/tests/visual/boards/board_template.spec.ts-snapshots/board-template-chrome-linux.png b/e2e-tests/playwright/tests/visual/boards/board_template.spec.ts-snapshots/board-template-chrome-linux.png similarity index 100% rename from e2e/playwright/tests/visual/boards/board_template.spec.ts-snapshots/board-template-chrome-linux.png rename to e2e-tests/playwright/tests/visual/boards/board_template.spec.ts-snapshots/board-template-chrome-linux.png diff --git a/e2e/playwright/tests/visual/boards/board_template.spec.ts-snapshots/board-template-firefox-linux.png b/e2e-tests/playwright/tests/visual/boards/board_template.spec.ts-snapshots/board-template-firefox-linux.png similarity index 100% rename from e2e/playwright/tests/visual/boards/board_template.spec.ts-snapshots/board-template-firefox-linux.png rename to e2e-tests/playwright/tests/visual/boards/board_template.spec.ts-snapshots/board-template-firefox-linux.png diff --git a/e2e/playwright/tests/visual/boards/board_template.spec.ts-snapshots/board-template-ipad-linux.png b/e2e-tests/playwright/tests/visual/boards/board_template.spec.ts-snapshots/board-template-ipad-linux.png similarity index 100% rename from e2e/playwright/tests/visual/boards/board_template.spec.ts-snapshots/board-template-ipad-linux.png rename to e2e-tests/playwright/tests/visual/boards/board_template.spec.ts-snapshots/board-template-ipad-linux.png diff --git a/e2e/playwright/tests/visual/boards/view_untitled_board.spec.ts b/e2e-tests/playwright/tests/visual/boards/view_untitled_board.spec.ts similarity index 100% rename from e2e/playwright/tests/visual/boards/view_untitled_board.spec.ts rename to e2e-tests/playwright/tests/visual/boards/view_untitled_board.spec.ts diff --git a/e2e/playwright/tests/visual/boards/view_untitled_board.spec.ts-snapshots/view-untitled-board-chrome-linux.png b/e2e-tests/playwright/tests/visual/boards/view_untitled_board.spec.ts-snapshots/view-untitled-board-chrome-linux.png similarity index 100% rename from e2e/playwright/tests/visual/boards/view_untitled_board.spec.ts-snapshots/view-untitled-board-chrome-linux.png rename to e2e-tests/playwright/tests/visual/boards/view_untitled_board.spec.ts-snapshots/view-untitled-board-chrome-linux.png diff --git a/e2e/playwright/tests/visual/boards/view_untitled_board.spec.ts-snapshots/view-untitled-board-firefox-linux.png b/e2e-tests/playwright/tests/visual/boards/view_untitled_board.spec.ts-snapshots/view-untitled-board-firefox-linux.png similarity index 100% rename from e2e/playwright/tests/visual/boards/view_untitled_board.spec.ts-snapshots/view-untitled-board-firefox-linux.png rename to e2e-tests/playwright/tests/visual/boards/view_untitled_board.spec.ts-snapshots/view-untitled-board-firefox-linux.png diff --git a/e2e/playwright/tests/visual/boards/view_untitled_board.spec.ts-snapshots/view-untitled-board-ipad-linux.png b/e2e-tests/playwright/tests/visual/boards/view_untitled_board.spec.ts-snapshots/view-untitled-board-ipad-linux.png similarity index 100% rename from e2e/playwright/tests/visual/boards/view_untitled_board.spec.ts-snapshots/view-untitled-board-ipad-linux.png rename to e2e-tests/playwright/tests/visual/boards/view_untitled_board.spec.ts-snapshots/view-untitled-board-ipad-linux.png diff --git a/e2e/playwright/tests/visual/channels/intro_channel.spec.ts b/e2e-tests/playwright/tests/visual/channels/intro_channel.spec.ts similarity index 100% rename from e2e/playwright/tests/visual/channels/intro_channel.spec.ts rename to e2e-tests/playwright/tests/visual/channels/intro_channel.spec.ts diff --git a/e2e/playwright/tests/visual/channels/intro_channel.spec.ts-snapshots/intro-to-channel-as-regular-user-chrome-linux.png b/e2e-tests/playwright/tests/visual/channels/intro_channel.spec.ts-snapshots/intro-to-channel-as-regular-user-chrome-linux.png similarity index 100% rename from e2e/playwright/tests/visual/channels/intro_channel.spec.ts-snapshots/intro-to-channel-as-regular-user-chrome-linux.png rename to e2e-tests/playwright/tests/visual/channels/intro_channel.spec.ts-snapshots/intro-to-channel-as-regular-user-chrome-linux.png diff --git a/e2e/playwright/tests/visual/channels/intro_channel.spec.ts-snapshots/intro-to-channel-as-regular-user-firefox-linux.png b/e2e-tests/playwright/tests/visual/channels/intro_channel.spec.ts-snapshots/intro-to-channel-as-regular-user-firefox-linux.png similarity index 100% rename from e2e/playwright/tests/visual/channels/intro_channel.spec.ts-snapshots/intro-to-channel-as-regular-user-firefox-linux.png rename to e2e-tests/playwright/tests/visual/channels/intro_channel.spec.ts-snapshots/intro-to-channel-as-regular-user-firefox-linux.png diff --git a/e2e/playwright/tests/visual/channels/intro_channel.spec.ts-snapshots/intro-to-channel-as-regular-user-ipad-linux.png b/e2e-tests/playwright/tests/visual/channels/intro_channel.spec.ts-snapshots/intro-to-channel-as-regular-user-ipad-linux.png similarity index 100% rename from e2e/playwright/tests/visual/channels/intro_channel.spec.ts-snapshots/intro-to-channel-as-regular-user-ipad-linux.png rename to e2e-tests/playwright/tests/visual/channels/intro_channel.spec.ts-snapshots/intro-to-channel-as-regular-user-ipad-linux.png diff --git a/e2e/playwright/tests/visual/channels/intro_channel.spec.ts-snapshots/intro-to-channel-as-regular-user-iphone-linux.png b/e2e-tests/playwright/tests/visual/channels/intro_channel.spec.ts-snapshots/intro-to-channel-as-regular-user-iphone-linux.png similarity index 100% rename from e2e/playwright/tests/visual/channels/intro_channel.spec.ts-snapshots/intro-to-channel-as-regular-user-iphone-linux.png rename to e2e-tests/playwright/tests/visual/channels/intro_channel.spec.ts-snapshots/intro-to-channel-as-regular-user-iphone-linux.png diff --git a/e2e/playwright/tests/visual/common/landing_page.spec.ts b/e2e-tests/playwright/tests/visual/common/landing_page.spec.ts similarity index 100% rename from e2e/playwright/tests/visual/common/landing_page.spec.ts rename to e2e-tests/playwright/tests/visual/common/landing_page.spec.ts diff --git a/e2e/playwright/tests/visual/common/landing_page.spec.ts-snapshots/landing-login-chrome-linux.png b/e2e-tests/playwright/tests/visual/common/landing_page.spec.ts-snapshots/landing-login-chrome-linux.png similarity index 100% rename from e2e/playwright/tests/visual/common/landing_page.spec.ts-snapshots/landing-login-chrome-linux.png rename to e2e-tests/playwright/tests/visual/common/landing_page.spec.ts-snapshots/landing-login-chrome-linux.png diff --git a/e2e/playwright/tests/visual/common/landing_page.spec.ts-snapshots/landing-login-firefox-linux.png b/e2e-tests/playwright/tests/visual/common/landing_page.spec.ts-snapshots/landing-login-firefox-linux.png similarity index 100% rename from e2e/playwright/tests/visual/common/landing_page.spec.ts-snapshots/landing-login-firefox-linux.png rename to e2e-tests/playwright/tests/visual/common/landing_page.spec.ts-snapshots/landing-login-firefox-linux.png diff --git a/e2e/playwright/tests/visual/common/landing_page.spec.ts-snapshots/landing-login-ipad-linux.png b/e2e-tests/playwright/tests/visual/common/landing_page.spec.ts-snapshots/landing-login-ipad-linux.png similarity index 100% rename from e2e/playwright/tests/visual/common/landing_page.spec.ts-snapshots/landing-login-ipad-linux.png rename to e2e-tests/playwright/tests/visual/common/landing_page.spec.ts-snapshots/landing-login-ipad-linux.png diff --git a/e2e/playwright/tests/visual/common/landing_page.spec.ts-snapshots/landing-login-iphone-linux.png b/e2e-tests/playwright/tests/visual/common/landing_page.spec.ts-snapshots/landing-login-iphone-linux.png similarity index 100% rename from e2e/playwright/tests/visual/common/landing_page.spec.ts-snapshots/landing-login-iphone-linux.png rename to e2e-tests/playwright/tests/visual/common/landing_page.spec.ts-snapshots/landing-login-iphone-linux.png diff --git a/e2e/playwright/tests/visual/common/login.spec.ts b/e2e-tests/playwright/tests/visual/common/login.spec.ts similarity index 100% rename from e2e/playwright/tests/visual/common/login.spec.ts rename to e2e-tests/playwright/tests/visual/common/login.spec.ts diff --git a/e2e/playwright/tests/visual/common/login.spec.ts-snapshots/login-chrome-linux.png b/e2e-tests/playwright/tests/visual/common/login.spec.ts-snapshots/login-chrome-linux.png similarity index 100% rename from e2e/playwright/tests/visual/common/login.spec.ts-snapshots/login-chrome-linux.png rename to e2e-tests/playwright/tests/visual/common/login.spec.ts-snapshots/login-chrome-linux.png diff --git a/e2e/playwright/tests/visual/common/login.spec.ts-snapshots/login-error-chrome-linux.png b/e2e-tests/playwright/tests/visual/common/login.spec.ts-snapshots/login-error-chrome-linux.png similarity index 100% rename from e2e/playwright/tests/visual/common/login.spec.ts-snapshots/login-error-chrome-linux.png rename to e2e-tests/playwright/tests/visual/common/login.spec.ts-snapshots/login-error-chrome-linux.png diff --git a/e2e/playwright/tests/visual/common/login.spec.ts-snapshots/login-error-firefox-linux.png b/e2e-tests/playwright/tests/visual/common/login.spec.ts-snapshots/login-error-firefox-linux.png similarity index 100% rename from e2e/playwright/tests/visual/common/login.spec.ts-snapshots/login-error-firefox-linux.png rename to e2e-tests/playwright/tests/visual/common/login.spec.ts-snapshots/login-error-firefox-linux.png diff --git a/e2e/playwright/tests/visual/common/login.spec.ts-snapshots/login-error-ipad-linux.png b/e2e-tests/playwright/tests/visual/common/login.spec.ts-snapshots/login-error-ipad-linux.png similarity index 100% rename from e2e/playwright/tests/visual/common/login.spec.ts-snapshots/login-error-ipad-linux.png rename to e2e-tests/playwright/tests/visual/common/login.spec.ts-snapshots/login-error-ipad-linux.png diff --git a/e2e/playwright/tests/visual/common/login.spec.ts-snapshots/login-error-iphone-linux.png b/e2e-tests/playwright/tests/visual/common/login.spec.ts-snapshots/login-error-iphone-linux.png similarity index 100% rename from e2e/playwright/tests/visual/common/login.spec.ts-snapshots/login-error-iphone-linux.png rename to e2e-tests/playwright/tests/visual/common/login.spec.ts-snapshots/login-error-iphone-linux.png diff --git a/e2e/playwright/tests/visual/common/login.spec.ts-snapshots/login-firefox-linux.png b/e2e-tests/playwright/tests/visual/common/login.spec.ts-snapshots/login-firefox-linux.png similarity index 100% rename from e2e/playwright/tests/visual/common/login.spec.ts-snapshots/login-firefox-linux.png rename to e2e-tests/playwright/tests/visual/common/login.spec.ts-snapshots/login-firefox-linux.png diff --git a/e2e/playwright/tests/visual/common/login.spec.ts-snapshots/login-ipad-linux.png b/e2e-tests/playwright/tests/visual/common/login.spec.ts-snapshots/login-ipad-linux.png similarity index 100% rename from e2e/playwright/tests/visual/common/login.spec.ts-snapshots/login-ipad-linux.png rename to e2e-tests/playwright/tests/visual/common/login.spec.ts-snapshots/login-ipad-linux.png diff --git a/e2e/playwright/tests/visual/common/login.spec.ts-snapshots/login-iphone-linux.png b/e2e-tests/playwright/tests/visual/common/login.spec.ts-snapshots/login-iphone-linux.png similarity index 100% rename from e2e/playwright/tests/visual/common/login.spec.ts-snapshots/login-iphone-linux.png rename to e2e-tests/playwright/tests/visual/common/login.spec.ts-snapshots/login-iphone-linux.png diff --git a/e2e/playwright/tests/visual/common/signup_email.spec.ts b/e2e-tests/playwright/tests/visual/common/signup_email.spec.ts similarity index 100% rename from e2e/playwright/tests/visual/common/signup_email.spec.ts rename to e2e-tests/playwright/tests/visual/common/signup_email.spec.ts diff --git a/e2e/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-chrome-linux.png b/e2e-tests/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-chrome-linux.png similarity index 100% rename from e2e/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-chrome-linux.png rename to e2e-tests/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-chrome-linux.png diff --git a/e2e/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-error-chrome-linux.png b/e2e-tests/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-error-chrome-linux.png similarity index 100% rename from e2e/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-error-chrome-linux.png rename to e2e-tests/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-error-chrome-linux.png diff --git a/e2e/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-error-firefox-linux.png b/e2e-tests/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-error-firefox-linux.png similarity index 100% rename from e2e/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-error-firefox-linux.png rename to e2e-tests/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-error-firefox-linux.png diff --git a/e2e/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-error-ipad-linux.png b/e2e-tests/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-error-ipad-linux.png similarity index 100% rename from e2e/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-error-ipad-linux.png rename to e2e-tests/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-error-ipad-linux.png diff --git a/e2e/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-error-iphone-linux.png b/e2e-tests/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-error-iphone-linux.png similarity index 100% rename from e2e/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-error-iphone-linux.png rename to e2e-tests/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-error-iphone-linux.png diff --git a/e2e/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-firefox-linux.png b/e2e-tests/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-firefox-linux.png similarity index 100% rename from e2e/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-firefox-linux.png rename to e2e-tests/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-firefox-linux.png diff --git a/e2e/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-ipad-linux.png b/e2e-tests/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-ipad-linux.png similarity index 100% rename from e2e/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-ipad-linux.png rename to e2e-tests/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-ipad-linux.png diff --git a/e2e/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-iphone-linux.png b/e2e-tests/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-iphone-linux.png similarity index 100% rename from e2e/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-iphone-linux.png rename to e2e-tests/playwright/tests/visual/common/signup_email.spec.ts-snapshots/signup-email-iphone-linux.png diff --git a/e2e/playwright/tsconfig.json b/e2e-tests/playwright/tsconfig.json similarity index 100% rename from e2e/playwright/tsconfig.json rename to e2e-tests/playwright/tsconfig.json From b7be613ed7602beaede859d9f895f65542a7688f Mon Sep 17 00:00:00 2001 From: Agniva De Sarker Date: Tue, 28 Mar 2023 21:45:36 +0530 Subject: [PATCH 34/46] MM-51744: Ignore http.ErrServerClosed from Playbooks metricsServer (#22708) https://mattermost.atlassian.net/browse/MM-51744 ```release-note NONE ``` --- server/playbooks/product/playbooks_product.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/playbooks/product/playbooks_product.go b/server/playbooks/product/playbooks_product.go index 77360db7cd..8f2f98dcdf 100644 --- a/server/playbooks/product/playbooks_product.go +++ b/server/playbooks/product/playbooks_product.go @@ -582,7 +582,7 @@ func (pp *playbooksProduct) runMetricsServer() { // Run server to expose metrics go func() { err := pp.metricsServer.Run() - if err != nil { + if err != nil && !errors.Is(err, http.ErrServerClosed) { logrus.WithError(err).Error("Metrics server could not be started") } }() From bb939e28c9b7c8b0ca131b6a11a410f7711ad26a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Andr=C3=A9s=20V=C3=A9lez=20Vidal?= Date: Tue, 28 Mar 2023 18:57:09 +0200 Subject: [PATCH 35/46] MM-49869 - add channels button lhs sidebar (#22701) --- .../src/actions/views/add_channel_dropdown.ts | 7 + .../add_channels_cta_button.test.tsx.snap | 46 ++++++ .../invite_members_button.test.tsx.snap | 2 +- .../sidebar/add_channel_dropdown.tsx | 14 +- .../sidebar/add_channels_cta_button.test.tsx | 148 +++++++++++++++++ .../sidebar/add_channels_cta_button.tsx | 155 ++++++++++++++++++ .../sidebar/invite_members_button.tsx | 6 +- .../sidebar_category/sidebar_category.tsx | 10 ++ webapp/channels/src/i18n/en.json | 3 + .../views/add_channel_cta_dropdown.ts | 21 +++ webapp/channels/src/reducers/views/index.ts | 2 + .../src/sass/layout/_sidebar-left.scss | 79 ++++++--- .../selectors/views/add_channel_dropdown.ts | 4 + webapp/channels/src/types/store/views.ts | 4 + webapp/channels/src/utils/constants.tsx | 2 + 15 files changed, 464 insertions(+), 39 deletions(-) create mode 100644 webapp/channels/src/components/sidebar/__snapshots__/add_channels_cta_button.test.tsx.snap create mode 100644 webapp/channels/src/components/sidebar/add_channels_cta_button.test.tsx create mode 100644 webapp/channels/src/components/sidebar/add_channels_cta_button.tsx create mode 100644 webapp/channels/src/reducers/views/add_channel_cta_dropdown.ts diff --git a/webapp/channels/src/actions/views/add_channel_dropdown.ts b/webapp/channels/src/actions/views/add_channel_dropdown.ts index 55bef92f84..251d2acf5e 100644 --- a/webapp/channels/src/actions/views/add_channel_dropdown.ts +++ b/webapp/channels/src/actions/views/add_channel_dropdown.ts @@ -9,3 +9,10 @@ export function setAddChannelDropdown(open: boolean) { open, }; } + +export function setAddChannelCtaDropdown(open: boolean) { + return { + type: ActionTypes.ADD_CHANNEL_CTA_DROPDOWN_TOGGLE, + open, + }; +} diff --git a/webapp/channels/src/components/sidebar/__snapshots__/add_channels_cta_button.test.tsx.snap b/webapp/channels/src/components/sidebar/__snapshots__/add_channels_cta_button.test.tsx.snap new file mode 100644 index 0000000000..6b9383a1d6 --- /dev/null +++ b/webapp/channels/src/components/sidebar/__snapshots__/add_channels_cta_button.test.tsx.snap @@ -0,0 +1,46 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`components/new_channel_modal should match snapshot 1`] = ` + + + + + + + + + +`; diff --git a/webapp/channels/src/components/sidebar/__snapshots__/invite_members_button.test.tsx.snap b/webapp/channels/src/components/sidebar/__snapshots__/invite_members_button.test.tsx.snap index 16252a1eb0..809f40e20d 100644 --- a/webapp/channels/src/components/sidebar/__snapshots__/invite_members_button.test.tsx.snap +++ b/webapp/channels/src/components/sidebar/__snapshots__/invite_members_button.test.tsx.snap @@ -82,7 +82,7 @@ exports[`components/sidebar/invite_members_button should match snapshot 1`] = ` >
  • - <> - - + { + const original = jest.requireActual('actions/telemetry_actions.jsx'); + return { + ...original, + trackEvent: jest.fn(), + }; +}); + +const mockDispatch = jest.fn(); +let mockState: GlobalState; + +jest.mock('react-redux', () => ({ + ...jest.requireActual('react-redux') as typeof import('react-redux'), + useSelector: (selector: (state: typeof mockState) => unknown) => selector(mockState), + useDispatch: () => mockDispatch, +})); + +describe('components/new_channel_modal', () => { + beforeEach(() => { + mockState = { + entities: { + general: { + config: {}, + }, + channels: { + currentChannelId: 'current_channel_id', + channels: {}, + roles: { + current_channel_id: [ + 'channel_user', + 'channel_admin', + ], + }, + }, + teams: { + currentTeamId: 'current_team_id', + myMembers: { + current_team_id: { + roles: 'team_user team_admin', + }, + }, + teams: { + current_team_id: { + id: 'current_team_id', + description: 'Curent team description', + name: 'current-team', + }, + }, + }, + preferences: { + myPreferences: {}, + }, + users: { + currentUserId: 'current_user_id', + profiles: { + current_user_id: {roles: 'system_user'}, + }, + }, + roles: { + roles: { + guest_user: { + permissions: [], + }, + system_user: { + permissions: [Permissions.JOIN_PUBLIC_CHANNELS, Permissions.CREATE_PRIVATE_CHANNEL, Permissions.CREATE_PUBLIC_CHANNEL], + }, + }, + }, + }, + views: { + addChannelCtaDropdown: { + isOpen: false, + }, + }, + } as unknown as GlobalState; + }); + + test('should match snapshot', () => { + expect( + shallow( + , + ), + ).toMatchSnapshot(); + }); + + test('should find the add channels button when user has permissions', () => { + const wrapper = mountWithIntl( + , + ); + expect(wrapper.find('.AddChannelsCtaDropdown').exists()).toBeTruthy(); + }); + + test('should return nothing when user does not have permissions', () => { + const guestUser = { + currentUserId: 'guest_user_id', + profiles: { + user_id: { + id: 'guest_user_id', + roles: 'team_role', + }, + }, + } as unknown as UsersState; + mockState = {...mockState, entities: {...mockState.entities, users: guestUser}}; + + const wrapper = mountWithIntl( + , + ); + expect(wrapper.find('.AddChannelsCtaDropdown').exists()).toBeFalsy(); + }); + + test('should fire dispatch to save preferences when button is clicked', () => { + const wrapper = mountWithIntl( + , + ); + const button = wrapper.find('.AddChannelsCtaDropdown button'); + expect(mockDispatch).not.toHaveBeenCalled(); + button.simulate('click'); + expect(mockDispatch).toHaveBeenCalled(); + }); + + test('should fire trackEvent to send telemetry when button is clicked', () => { + const wrapper = mountWithIntl( + , + ); + + const button = wrapper.find('.AddChannelsCtaDropdown button'); + expect(mockDispatch).not.toHaveBeenCalled(); + button.simulate('click'); + + expect(trackEvent).toHaveBeenCalledWith('ui', 'add_channels_cta_button_clicked'); + }); +}); diff --git a/webapp/channels/src/components/sidebar/add_channels_cta_button.tsx b/webapp/channels/src/components/sidebar/add_channels_cta_button.tsx new file mode 100644 index 0000000000..07ed64b9e5 --- /dev/null +++ b/webapp/channels/src/components/sidebar/add_channels_cta_button.tsx @@ -0,0 +1,155 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React, {useCallback} from 'react'; + +import {useIntl} from 'react-intl'; + +import {useSelector, useDispatch} from 'react-redux'; + +import MenuWrapper from 'components/widgets/menu/menu_wrapper'; +import Menu from 'components/widgets/menu/menu'; +import MoreChannels from 'components/more_channels'; +import NewChannelModal from 'components/new_channel_modal/new_channel_modal'; + +import {isAddChannelCtaDropdownOpen} from 'selectors/views/add_channel_dropdown'; + +import {GlobalState} from 'types/store'; + +import {getCurrentTeamId} from 'mattermost-redux/selectors/entities/teams'; +import {haveICurrentChannelPermission} from 'mattermost-redux/selectors/entities/roles'; +import {DispatchFunc} from 'mattermost-redux/types/actions'; +import Permissions from 'mattermost-redux/constants/permissions'; +import {getBool} from 'mattermost-redux/selectors/entities/preferences'; +import {savePreferences} from 'mattermost-redux/actions/preferences'; +import {getCurrentUserId} from 'mattermost-redux/selectors/entities/common'; + +import {setAddChannelCtaDropdown} from 'actions/views/add_channel_dropdown'; +import {openModal} from 'actions/views/modals'; +import {trackEvent} from 'actions/telemetry_actions'; + +import {ModalIdentifiers, Preferences, Touched} from 'utils/constants'; + +const AddChannelsCtaButton = (): JSX.Element | null => { + const dispatch = useDispatch(); + const currentTeamId = useSelector(getCurrentTeamId); + const intl = useIntl(); + const touchedAddChannelsCtaButton = useSelector((state: GlobalState) => getBool(state, Preferences.TOUCHED, Touched.ADD_CHANNELS_CTA)); + + const canCreatePublicChannel = useSelector((state: GlobalState) => haveICurrentChannelPermission(state, Permissions.CREATE_PUBLIC_CHANNEL)); + const canCreatePrivateChannel = useSelector((state: GlobalState) => haveICurrentChannelPermission(state, Permissions.CREATE_PRIVATE_CHANNEL)); + const canCreateChannel = canCreatePrivateChannel || canCreatePublicChannel; + const canJoinPublicChannel = useSelector((state: GlobalState) => haveICurrentChannelPermission(state, Permissions.JOIN_PUBLIC_CHANNELS)); + const isAddChannelCtaOpen = useSelector(isAddChannelCtaDropdownOpen); + const currentUserId = useSelector(getCurrentUserId); + const openAddChannelsCtaOpen = useCallback((open: boolean) => { + dispatch(setAddChannelCtaDropdown(open)); + }, []); + + let buttonClass = 'SidebarChannelNavigator__addChannelsCtaLhsButton'; + + if (!touchedAddChannelsCtaButton) { + buttonClass += ' SidebarChannelNavigator__addChannelsCtaLhsButton--untouched'; + } + + if ((!canCreateChannel && !canJoinPublicChannel) || !currentTeamId) { + return null; + } + + const showMoreChannelsModal = () => { + dispatch(openModal({ + modalId: ModalIdentifiers.MORE_CHANNELS, + dialogType: MoreChannels, + dialogProps: {morePublicChannelsModalType: 'public'}, + })); + trackEvent('ui', 'browse_channels_button_is_clicked'); + }; + + const showNewChannelModal = () => { + dispatch(openModal({ + modalId: ModalIdentifiers.NEW_CHANNEL_MODAL, + dialogType: NewChannelModal, + })); + trackEvent('ui', 'create_new_channel_button_is_clicked'); + }; + + const renderDropdownItems = () => { + let joinPublicChannel; + if (canJoinPublicChannel) { + joinPublicChannel = ( + + ); + } + + let createChannel; + if (canCreateChannel) { + createChannel = ( + + ); + } + + return ( + <> + + {createChannel} + {joinPublicChannel} + + + ); + }; + + const trackOpen = (opened: boolean) => { + openAddChannelsCtaOpen(opened); + trackEvent('ui', 'add_channels_cta_button_clicked'); + if (!touchedAddChannelsCtaButton) { + dispatch(savePreferences( + currentUserId, + [{ + category: Preferences.TOUCHED, + user_id: currentUserId, + name: Touched.ADD_CHANNELS_CTA, + value: 'true', + }], + )); + } + }; + + return ( + + + + {renderDropdownItems()} + + + ); +}; + +export default AddChannelsCtaButton; diff --git a/webapp/channels/src/components/sidebar/invite_members_button.tsx b/webapp/channels/src/components/sidebar/invite_members_button.tsx index 0ff3799858..0f3f602d5f 100644 --- a/webapp/channels/src/components/sidebar/invite_members_button.tsx +++ b/webapp/channels/src/components/sidebar/invite_members_button.tsx @@ -32,7 +32,7 @@ type Props = { isAdmin: boolean; } -const InviteMembersButton: React.FC = (props: Props): JSX.Element | null => { +const InviteMembersButton = (props: Props): JSX.Element | null => { const dispatch = useDispatch(); const intl = useIntl(); @@ -50,10 +50,10 @@ const InviteMembersButton: React.FC = (props: Props): JSX.Element | null props.onClick(); }; - let buttonClass = 'SidebarChannelNavigator_inviteMembersLhsButton'; + let buttonClass = 'SidebarChannelNavigator__inviteMembersLhsButton'; if (!props.touchedInviteMembersButton && Number(totalUserCount) <= Constants.USER_LIMIT) { - buttonClass += ' SidebarChannelNavigator_inviteMembersLhsButton--untouched'; + buttonClass += ' SidebarChannelNavigator__inviteMembersLhsButton--untouched'; } if (!currentTeamId || !totalUserCount) { diff --git a/webapp/channels/src/components/sidebar/sidebar_category/sidebar_category.tsx b/webapp/channels/src/components/sidebar/sidebar_category/sidebar_category.tsx index fe33dd7da6..c770a146f6 100644 --- a/webapp/channels/src/components/sidebar/sidebar_category/sidebar_category.tsx +++ b/webapp/channels/src/components/sidebar/sidebar_category/sidebar_category.tsx @@ -24,6 +24,8 @@ import KeyboardShortcutSequence, { KEYBOARD_SHORTCUTS, } from 'components/keyboard_shortcuts/keyboard_shortcuts_sequence'; +import AddChannelsCtaButton from '../add_channels_cta_button'; + import SidebarCategorySortingMenu from './sidebar_category_sorting_menu'; import SidebarCategoryMenu from './sidebar_category_menu'; @@ -342,6 +344,13 @@ export default class SidebarCategory extends React.PureComponent { ); } + let addChannelsCtaButton = null; + if (category.type === 'channels' && !category.collapsed) { + addChannelsCtaButton = ( + + ); + } + return (
    { }} {inviteMembersButton} + {addChannelsCtaButton}
    ); }} diff --git a/webapp/channels/src/i18n/en.json b/webapp/channels/src/i18n/en.json index 2b69918b75..b7458e403a 100644 --- a/webapp/channels/src/i18n/en.json +++ b/webapp/channels/src/i18n/en.json @@ -4854,6 +4854,7 @@ "shortcuts.team_nav.prev.mac": "Previous team:\t⌘|⌥|Up", "shortcuts.team_nav.switcher": "Navigate to a specific team:\tCtrl|Alt|[1-9]", "shortcuts.team_nav.switcher.mac": "Navigate to a specific team:\t⌘|⌥|[1-9]", + "sidebar_left.add_channel_cta_dropdown.dropdownAriaLabel": "Add Channel Dropdown", "sidebar_left.add_channel_dropdown.browseChannels": "Browse Channels", "sidebar_left.add_channel_dropdown.browseOrCreateChannels": "Browse or create channels", "sidebar_left.add_channel_dropdown.createCategory": "Create New Category", @@ -4863,6 +4864,7 @@ "sidebar_left.add_channel_dropdown.invitePeopleExtraText": "Add people to the team", "sidebar_left.add_channel_dropdown.work_template": "Create from a template", "sidebar_left.add_channel_dropdown.work_template_extra": "Set up a channel with linked boards, and playbooks", + "sidebar_left.addChannelsCta": "Add channels", "sidebar_left.channel_filter.filterByUnread": "Filter by unread", "sidebar_left.channel_filter.filterUnreadAria": "unreads filter", "sidebar_left.channel_filter.showAllChannels": "Show all channels", @@ -4901,6 +4903,7 @@ "sidebar_left.sidebar_channel_menu.unfavoriteChannel": "Unfavorite", "sidebar_left.sidebar_channel_menu.unmuteChannel": "Unmute Channel", "sidebar_left.sidebar_channel_menu.unmuteConversation": "Unmute Conversation", + "sidebar_left.sidebar_channel_navigator.addChannelsCta": "Add channels", "sidebar_left.sidebar_channel_navigator.inviteUsers": "Invite Users", "sidebar_left.sidebar_channel.selectedCount": "{count} selected", "sidebar_right_menu.console": "System Console", diff --git a/webapp/channels/src/reducers/views/add_channel_cta_dropdown.ts b/webapp/channels/src/reducers/views/add_channel_cta_dropdown.ts new file mode 100644 index 0000000000..c468169bac --- /dev/null +++ b/webapp/channels/src/reducers/views/add_channel_cta_dropdown.ts @@ -0,0 +1,21 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {combineReducers} from 'redux'; + +import {GenericAction} from 'mattermost-redux/types/actions'; + +import {ActionTypes} from 'utils/constants'; + +export function isOpen(state = false, action: GenericAction) { + switch (action.type) { + case ActionTypes.ADD_CHANNEL_CTA_DROPDOWN_TOGGLE: + return action.open; + default: + return state; + } +} + +export default combineReducers({ + isOpen, +}); diff --git a/webapp/channels/src/reducers/views/index.ts b/webapp/channels/src/reducers/views/index.ts index 2f574e32ba..6d305e40d8 100644 --- a/webapp/channels/src/reducers/views/index.ts +++ b/webapp/channels/src/reducers/views/index.ts @@ -25,6 +25,7 @@ import productMenu from './product_menu'; import textbox from './textbox'; import statusDropdown from './status_dropdown'; import addChannelDropdown from './add_channel_dropdown'; +import addChannelCtaDropdown from './add_channel_cta_dropdown'; import threads from './threads'; import onboardingTasks from './onboarding_tasks'; @@ -50,6 +51,7 @@ export default combineReducers({ channelSidebar, statusDropdown, addChannelDropdown, + addChannelCtaDropdown, onboardingTasks, threads, productMenu, diff --git a/webapp/channels/src/sass/layout/_sidebar-left.scss b/webapp/channels/src/sass/layout/_sidebar-left.scss index 8baf4ac923..c670182893 100644 --- a/webapp/channels/src/sass/layout/_sidebar-left.scss +++ b/webapp/channels/src/sass/layout/_sidebar-left.scss @@ -178,6 +178,46 @@ $sidebarOpacityAnimationDuration: 0.15s; } } + &__inviteMembersLhsButton, + &__addChannelsCtaLhsButton { + display: flex; + padding: 6px 0; + margin-left: 15px; + color: rgba(var(--sidebar-text-rgb), 0.72); + line-height: 20px; + list-style: none; + + i { + font-size: 20px; + } + + span { + align-self: flex-end; + margin-top: -2px; + margin-left: 5px; + } + + &--untouched { + color: var(--sidebar-unread-text); + font-weight: $font-weight--semibold; + + i::before { + font-weight: $font-weight--semibold; + } + } + } + + &__addChannelsCtaLhsButton { + border: none; + margin-left: 0; + background: none; + + li { + display: flex; + margin-left: 15px; + } + } + .AddChannelDropdown_dropdownButton, .SidebarChannelNavigator_inviteUsers, .SidebarChannelNavigator_jumpToButton, @@ -700,35 +740,12 @@ $sidebarOpacityAnimationDuration: 0.15s; } } - .SidebarChannelNavigator_inviteMembersLhsButton { - display: flex; - padding: 6px 0; - margin-left: 15px; - color: rgba(var(--sidebar-text-rgb), 0.72); - line-height: 20px; - list-style: none; - - i { - font-size: 20px; - } - - span { - align-self: flex-end; - margin-top: -2px; - margin-left: 5px; - } - - &--untouched { - color: var(--sidebar-unread-text); - font-weight: $font-weight--semibold; - - i::before { - font-weight: $font-weight--semibold; - } - } + .AddChannelsCtaDropdown .dropdown-menu { + margin-left: 20px; } - #introTextInvite { + #introTextInvite, + #addChannelsCta { display: flex; width: 100%; @@ -737,6 +754,14 @@ $sidebarOpacityAnimationDuration: 0.15s; } } + #AddChannelCtaDropdown { + position: fixed; + + ul { + min-width: 232px !important; + } + } + .SidebarChannelNavigator_inviteUsersSticky { position: absolute; z-index: 2; diff --git a/webapp/channels/src/selectors/views/add_channel_dropdown.ts b/webapp/channels/src/selectors/views/add_channel_dropdown.ts index a106cb8602..84f41d9e9c 100644 --- a/webapp/channels/src/selectors/views/add_channel_dropdown.ts +++ b/webapp/channels/src/selectors/views/add_channel_dropdown.ts @@ -6,3 +6,7 @@ import {GlobalState} from 'types/store'; export function isAddChannelDropdownOpen(state: GlobalState) { return state.views.addChannelDropdown.isOpen; } + +export function isAddChannelCtaDropdownOpen(state: GlobalState) { + return state.views.addChannelCtaDropdown.isOpen; +} diff --git a/webapp/channels/src/types/store/views.ts b/webapp/channels/src/types/store/views.ts index 5e67a97ddd..19f34b7744 100644 --- a/webapp/channels/src/types/store/views.ts +++ b/webapp/channels/src/types/store/views.ts @@ -180,6 +180,10 @@ export type ViewsState = { isOpen: boolean; }; + addChannelCtaDropdown: { + isOpen: boolean; + }; + onboardingTasks: { isShowOnboardingTaskCompletion: boolean; isShowOnboardingCompleteProfileTour: boolean; diff --git a/webapp/channels/src/utils/constants.tsx b/webapp/channels/src/utils/constants.tsx index 5a5825ec5a..ad18170d15 100644 --- a/webapp/channels/src/utils/constants.tsx +++ b/webapp/channels/src/utils/constants.tsx @@ -163,6 +163,7 @@ export const Preferences = { // For one off things that have a special, attention-grabbing UI until you interact with them export const Touched = { INVITE_MEMBERS: 'invite_members', + ADD_CHANNELS_CTA: 'add_channels_cta', }; // Category for actions/interactions that will happen just once @@ -264,6 +265,7 @@ export const ActionTypes = keyMirror({ STATUS_DROPDOWN_TOGGLE: null, ADD_CHANNEL_DROPDOWN_TOGGLE: null, + ADD_CHANNEL_CTA_DROPDOWN_TOGGLE: null, SHOW_ONBOARDING_TASK_COMPLETION: null, SHOW_ONBOARDING_COMPLETE_PROFILE_TOUR: null, From 1cbfef65f178a01762a558930383e5c14a4d0abb Mon Sep 17 00:00:00 2001 From: Harrison Healey Date: Tue, 28 Mar 2023 15:34:06 -0400 Subject: [PATCH 36/46] MM-51683 Re-add CODEOWNERS for Web Platform files (#22627) --- CODEOWNERS | 8 ++++++++ webapp/channels/CODEOWNERS | 4 ---- 2 files changed, 8 insertions(+), 4 deletions(-) delete mode 100644 webapp/channels/CODEOWNERS diff --git a/CODEOWNERS b/CODEOWNERS index 39d5e668b6..07ee57d26c 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1 +1,9 @@ /plugin/ @mattermost/toolkit + +/.github/workflows/channels-ci.yml @mattermost/web-platform +/webapp/package.json @mattermost/web-platform +/webapp/channels/package.json @mattermost/web-platform +/webapp/Makefile @mattermost/web-platform +/webapp/package-lock.json @mattermost/web-platform +/webapp/platform/*/package.json @mattermost/web-platform +/webapp/scripts @mattermost/web-platform \ No newline at end of file diff --git a/webapp/channels/CODEOWNERS b/webapp/channels/CODEOWNERS deleted file mode 100644 index 7312e20fc8..0000000000 --- a/webapp/channels/CODEOWNERS +++ /dev/null @@ -1,4 +0,0 @@ -# Web Platform should be assigned to review all PRs that involve changing dependencies in the app, either intentional or accidental. -package.json @mattermost/web-platform -*/package.json @mattermost/web-platform -package-lock.json @mattermost/web-platform From fb2dac307baeb39220eb4d3b8949199eaffc35e0 Mon Sep 17 00:00:00 2001 From: Harrison Healey Date: Tue, 28 Mar 2023 15:36:04 -0400 Subject: [PATCH 37/46] MM-51735 Remove references to mattermost-redux from Boards (#22694) * MM-51735 Remove references to mattermost-redux from Boards * Fix styling and remove debug comments * Update Playbooks Jest config to point to mattermost-redux correctly --- webapp/boards/package.json | 1 - .../cloudUpgradeNudge/cloudUpgradeNudge.tsx | 2 +- webapp/boards/src/index.tsx | 18 +- webapp/boards/src/rudder.ts | 65 ++ .../src/types/mattermost-webapp/index.d.ts | 2 +- webapp/boards/webpack.config.js | 2 - webapp/package-lock.json | 633 +----------------- webapp/playbooks/jest.config.js | 1 + 8 files changed, 100 insertions(+), 624 deletions(-) create mode 100644 webapp/boards/src/rudder.ts diff --git a/webapp/boards/package.json b/webapp/boards/package.json index a66ffcfc34..574b95cb4c 100644 --- a/webapp/boards/package.json +++ b/webapp/boards/package.json @@ -45,7 +45,6 @@ "glob-parent": "6.0.2", "lodash": "^4.17.21", "marked": "^4.0.12", - "mattermost-redux": "5.33.1", "mini-create-react-context": "^0.4.1", "moment": "^2.29.1", "nanoevents": "^5.1.13", diff --git a/webapp/boards/src/components/cloudUpgradeNudge/cloudUpgradeNudge.tsx b/webapp/boards/src/components/cloudUpgradeNudge/cloudUpgradeNudge.tsx index 15789188b1..c33e02f61b 100644 --- a/webapp/boards/src/components/cloudUpgradeNudge/cloudUpgradeNudge.tsx +++ b/webapp/boards/src/components/cloudUpgradeNudge/cloudUpgradeNudge.tsx @@ -2,7 +2,7 @@ // See LICENSE.txt for license information. import React from 'react' -import {Post} from 'mattermost-redux/types/posts' +import {Post} from '@mattermost/types/posts' const PostTypeCloudUpgradeNudge = (props: {post: Post}): JSX.Element => { const ctaHandler = (e: React.MouseEvent) => { diff --git a/webapp/boards/src/index.tsx b/webapp/boards/src/index.tsx index 3e807e1b5a..c90d4417ec 100644 --- a/webapp/boards/src/index.tsx +++ b/webapp/boards/src/index.tsx @@ -6,16 +6,14 @@ import {Store, Action} from 'redux' import {Provider as ReduxProvider} from 'react-redux' import {createBrowserHistory, History} from 'history' -import {rudderAnalytics, RudderTelemetryHandler} from 'mattermost-redux/client/rudder' - -import {GlobalState} from 'mattermost-redux/types/store' - -import {selectTeam} from 'mattermost-redux/actions/teams' +import {GlobalState} from '@mattermost/types/store' import {SuiteWindow} from 'src/types/index' import {PluginRegistry} from 'src/types/mattermost-webapp' +import {rudderAnalytics, RudderTelemetryHandler} from 'src/rudder' + import appBarIcon from 'static/app-bar-icon.png' import {Constants} from 'src/constants' @@ -294,9 +292,13 @@ export default class Plugin { const currentUserId = mmStore.getState().entities.users.currentUserId if (currentTeamID !== fbPrevTeamID) { fbPrevTeamID = currentTeamID - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - mmStore.dispatch(selectTeam(currentTeamID)) + + mmStore.dispatch({ + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + type: 'SELECT_TEAM', + data: currentTeamID, + }) localStorage.setItem(`user_prev_team:${currentUserId}`, currentTeamID) } }) diff --git a/webapp/boards/src/rudder.ts b/webapp/boards/src/rudder.ts new file mode 100644 index 0000000000..aa94f377d7 --- /dev/null +++ b/webapp/boards/src/rudder.ts @@ -0,0 +1,65 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +// This file is duplicated from mattermost-redux in the web app with some slight modifications to make it standalone + +// As per rudder-sdk-js documentation, import this only once and use like a singleton. +// See https://github.com/rudderlabs/rudder-sdk-js#step-1-install-rudderstack-using-the-code-snippet +import * as rudderAnalytics from 'rudder-sdk-js' +export {rudderAnalytics} + +import {TelemetryHandler} from '@mattermost/client' + +import {Utils} from 'src/utils' + +export class RudderTelemetryHandler implements TelemetryHandler { + trackEvent(userId: string, userRoles: string, category: string, event: string, props?: any) { + const properties = Object.assign({ + category, + type: event, + user_actual_role: getActualRoles(userRoles), + user_actual_id: userId, + }, props) + const options = { + context: { + ip: '0.0.0.0', + }, + page: { + path: '', + referrer: '', + search: '', + title: '', + url: '', + }, + anonymousId: '00000000000000000000000000', + } + + rudderAnalytics.track('event', properties, options) + } + + pageVisited(userId: string, userRoles: string, category: string, name: string) { + rudderAnalytics.page( + category, + name, + { + path: '', + referrer: '', + search: '', + title: '', + url: '', + user_actual_role: getActualRoles(userRoles), + user_actual_id: userId, + }, + { + context: { + ip: '0.0.0.0', + }, + anonymousId: '00000000000000000000000000', + }, + ) + } +} + +function getActualRoles(userRoles: string) { + return userRoles && Utils.isSystemAdmin(userRoles) ? 'system_admin, system_user' : 'system_user' +} diff --git a/webapp/boards/src/types/mattermost-webapp/index.d.ts b/webapp/boards/src/types/mattermost-webapp/index.d.ts index a267533873..d713644170 100644 --- a/webapp/boards/src/types/mattermost-webapp/index.d.ts +++ b/webapp/boards/src/types/mattermost-webapp/index.d.ts @@ -3,7 +3,7 @@ import type React from 'react' -import type {Channel, ChannelMembership} from 'mattermost-redux/types/channels' +import type {Channel, ChannelMembership} from '@mattermost/types/channels' type ReactResolvable = React.ReactNode | React.ElementType diff --git a/webapp/boards/webpack.config.js b/webapp/boards/webpack.config.js index a9f7329090..2600760d48 100644 --- a/webapp/boards/webpack.config.js +++ b/webapp/boards/webpack.config.js @@ -53,8 +53,6 @@ const config = { resolve: { alias: { src: path.resolve(__dirname, './src/'), - // 'mattermost-redux': path.resolve(__dirname, '../channels/src/packages/mattermost-redux/src/'), - // reselect: path.resolve(__dirname, '../channels/src/packages/reselect/src/index'), '@mattermost/client': path.resolve(__dirname, '../platform/client/src/'), '@mattermost/components': path.resolve(__dirname, '../platform/components/src/'), }, diff --git a/webapp/package-lock.json b/webapp/package-lock.json index fc01c87174..0cd144544a 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -44,7 +44,6 @@ "glob-parent": "6.0.2", "lodash": "^4.17.21", "marked": "^4.0.12", - "mattermost-redux": "5.33.1", "mini-create-react-context": "^0.4.1", "moment": "^2.29.1", "nanoevents": "^5.1.13", @@ -8322,14 +8321,6 @@ "resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-2.0.0.tgz", "integrity": "sha512-Pc/AFTdwZwEKJxFJvlxrSmGe/di+aAOBn60sremrpLo6VI/6cmiUYNNwlI5KNYttg7uypzA3ILPMPgxB2GYZEg==" }, - "node_modules/@react-native-community/netinfo": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@react-native-community/netinfo/-/netinfo-4.7.0.tgz", - "integrity": "sha512-a/sDB+AsLEUNmhAUlAaTYeXKyQdFGBUfatqKkX5jluBo2CB3OAuTHfm7rSjcaLB9EmG5iSq3fOTpync2E7EYTA==", - "peerDependencies": { - "react-native": ">=0.59" - } - }, "node_modules/@redux-devtools/extension": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/@redux-devtools/extension/-/extension-3.2.3.tgz", @@ -13206,11 +13197,6 @@ "typescript": ">=3.x || >= 4.x" } }, - "node_modules/component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha512-jPatnhd33viNplKjqXKRkGU345p263OIWzDL2wH3LGIGp5Kojo+uXizHmOADRvhGFFTnJqX3jBAKP6vvmSDKcA==" - }, "node_modules/compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -17652,11 +17638,6 @@ "node": ">=8.0.0" } }, - "node_modules/get-params": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/get-params/-/get-params-0.1.2.tgz", - "integrity": "sha512-41eOxtlGgHQRbFyA8KTH+w+32Em3cRdfBud7j67ulzmIfmaHX9doq47s0fa4P5o9H64BZX9nrYI6sJvk46Op+Q==" - }, "node_modules/get-proxy": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/get-proxy/-/get-proxy-2.1.0.tgz", @@ -19292,6 +19273,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, "engines": { "node": ">=0.8.19" } @@ -21363,11 +21345,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsan": { - "version": "3.1.14", - "resolved": "https://registry.npmjs.org/jsan/-/jsan-3.1.14.tgz", - "integrity": "sha512-wStfgOJqMv4QKktuH273f5fyi3D3vy2pHOiSDGPvpcS/q+wb/M7AK3vkCcaHbkZxDOlDU/lDJgccygKSG2OhtA==" - }, "node_modules/jsdom": { "version": "16.7.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", @@ -21501,7 +21478,8 @@ "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true }, "node_modules/json-to-pretty-yaml": { "version": "1.2.2", @@ -21720,11 +21698,6 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, - "node_modules/linked-list": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/linked-list/-/linked-list-0.1.0.tgz", - "integrity": "sha512-Zr4ovrd0ODzF3ut2TWZMdHIxb8iFdJc/P3QM4iCJdlxxGHXo69c9hGIHzLo8/FtuR9E6WUZc5irKhtPUgOKMAg==" - }, "node_modules/listr2": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.5.tgz", @@ -22209,131 +22182,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/mattermost-redux": { - "version": "5.33.1", - "resolved": "https://registry.npmjs.org/mattermost-redux/-/mattermost-redux-5.33.1.tgz", - "integrity": "sha512-fHTW5PeB0xAE5u6uMds+hlWaJsUeWgE1034vekUah1X4bZCzBcMK4fM+ycGaIQ7c5Ylj9ML6Ni10XJYiQpMo5w==", - "dependencies": { - "core-js": "3.8.3", - "form-data": "3.0.0", - "gfycat-sdk": "1.4.18", - "moment-timezone": "0.5.32", - "redux": "4.0.5", - "redux-action-buffer": "1.2.0", - "redux-offline": "git+https://github.com/enahum/redux-offline.git#885024de96b6ec73650c340c8928066585c413df", - "redux-persist": "4.9.1", - "redux-persist-node-storage": "2.0.0", - "redux-thunk": "2.3.0", - "remote-redux-devtools": "0.5.16", - "reselect": "4.0.0", - "rudder-sdk-js": "1.0.14", - "serialize-error": "6.0.0", - "shallow-equals": "1.0.0" - } - }, - "node_modules/mattermost-redux/node_modules/core-js": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.8.3.tgz", - "integrity": "sha512-KPYXeVZYemC2TkNEkX/01I+7yd+nX3KddKwZ1Ww7SKWdI2wQprSgLmrTddT8nw92AjEklTsPBoSdQBhbI1bQ6Q==", - "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/mattermost-redux/node_modules/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==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/mattermost-redux/node_modules/moment-timezone": { - "version": "0.5.32", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.32.tgz", - "integrity": "sha512-Z8QNyuQHQAmWucp8Knmgei8YNo28aLjJq6Ma+jy1ZSpSk5nyfRT8xgUbSQvD2+2UajISfenndwvFuH3NGS+nvA==", - "dependencies": { - "moment": ">= 2.9.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/mattermost-redux/node_modules/redux": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz", - "integrity": "sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==", - "dependencies": { - "loose-envify": "^1.4.0", - "symbol-observable": "^1.2.0" - } - }, - "node_modules/mattermost-redux/node_modules/redux-persist": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-4.9.1.tgz", - "integrity": "sha512-XoOmfPyo9GEU/WLH9FgB47dNIN9l5ArjHes4o7vUWx9nxZoPxnVodhuHdyc4Ot+fMkdj3L2LTqSHhwrkr0QFUg==", - "dependencies": { - "json-stringify-safe": "^5.0.1", - "lodash": "^4.17.4", - "lodash-es": "^4.17.4" - } - }, - "node_modules/mattermost-redux/node_modules/redux-thunk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz", - "integrity": "sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw==" - }, - "node_modules/mattermost-redux/node_modules/reselect": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.0.0.tgz", - "integrity": "sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA==" - }, - "node_modules/mattermost-redux/node_modules/rudder-sdk-js": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/rudder-sdk-js/-/rudder-sdk-js-1.0.14.tgz", - "integrity": "sha512-q86qmF6VUXjTUCv1YRFc2V1pt408D641nD2ymKFaLtGZTLjkZCzotQ7cW8c48vPKlSWwekkBlA3kghy/NKGwOw==", - "deprecated": "1.x.x versions of the SDK are deprecated. Please upgrade to the latest (2.x.x) version" - }, - "node_modules/mattermost-redux/node_modules/serialize-error": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-6.0.0.tgz", - "integrity": "sha512-3vmBkMZLQO+BR4RPHcyRGdE09XCF6cvxzk2N2qn8Er3F91cy8Qt7VvEbZBOpaL53qsBbe2cFOefU6tRY6WDelA==", - "dependencies": { - "type-fest": "^0.12.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mattermost-redux/node_modules/symbol-observable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mattermost-redux/node_modules/type-fest": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.12.0.tgz", - "integrity": "sha512-53RyidyjvkGpnWPMF9bQgFtWp+Sl8O2Rp13VavmJgfAP9WWG6q6TkrKU8iyJdnwnfgHI6k2hTlgqH4aSdjoTbg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/mattermost-webapp": { "resolved": "channels", "link": true @@ -23313,6 +23161,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-localstorage/-/node-localstorage-1.3.1.tgz", "integrity": "sha512-NMWCSWWc6JbHT5PyWlNT2i8r7PgGYXVntmKawY83k/M0UJScZ5jirb61TLnqKwd815DfBQu+lR3sRw08SPzIaQ==", + "dev": true, "dependencies": { "write-file-atomic": "^1.1.4" }, @@ -23324,6 +23173,7 @@ "version": "1.3.4", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", "integrity": "sha512-SdrHoC/yVBPpV0Xq/mUZQIpW2sWXAShb/V4pomcJXh92RuaO+f3UTWItiR3Px+pLnV2PvC2/bfn5cwr5X6Vfxw==", + "dev": true, "dependencies": { "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", @@ -25425,6 +25275,7 @@ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz", "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==", "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "dev": true, "engines": { "node": ">=0.4.x" } @@ -26406,11 +26257,6 @@ "@babel/runtime": "^7.9.2" } }, - "node_modules/redux-action-buffer": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/redux-action-buffer/-/redux-action-buffer-1.2.0.tgz", - "integrity": "sha512-SvXSJQrn1Nsmza+xVMlvqZf0eiHIPV3I796jVC2DCC8X8+JXpAaSFuNxlxV0Cn+TAilat7KZ3srTwG5+HHL8tw==" - }, "node_modules/redux-batched-actions": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/redux-batched-actions/-/redux-batched-actions-0.5.0.tgz", @@ -26419,45 +26265,6 @@ "redux": ">=1.0.0" } }, - "node_modules/redux-devtools-core": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/redux-devtools-core/-/redux-devtools-core-0.2.1.tgz", - "integrity": "sha512-RAGOxtUFdr/1USAvxrWd+Gq/Euzgw7quCZlO5TgFpDfG7rB5tMhZUrNyBjpzgzL2yMk0eHnPYIGm7NkIfRzHxQ==", - "deprecated": "Package moved to @redux-devtools/app.", - "dependencies": { - "get-params": "^0.1.2", - "jsan": "^3.1.13", - "lodash": "^4.17.11", - "nanoid": "^2.0.0", - "remotedev-serialize": "^0.1.8" - } - }, - "node_modules/redux-devtools-core/node_modules/nanoid": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz", - "integrity": "sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==" - }, - "node_modules/redux-devtools-instrument": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/redux-devtools-instrument/-/redux-devtools-instrument-1.10.0.tgz", - "integrity": "sha512-X8JRBCzX2ADSMp+iiV7YQ8uoTNyEm0VPFPd4T854coz6lvRiBrFSqAr9YAS2n8Kzxx8CJQotR0QF9wsMM+3DvA==", - "deprecated": "Package moved to @redux-devtools/instrument.", - "dependencies": { - "lodash": "^4.17.19", - "symbol-observable": "^1.2.0" - }, - "peerDependencies": { - "redux": "^3.4.0 || ^4.0.0" - } - }, - "node_modules/redux-devtools-instrument/node_modules/symbol-observable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/redux-mock-store": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/redux-mock-store/-/redux-mock-store-1.5.4.tgz", @@ -26467,29 +26274,6 @@ "lodash.isplainobject": "^4.0.6" } }, - "node_modules/redux-offline": { - "version": "1.1.5", - "resolved": "git+ssh://git@github.com/enahum/redux-offline.git#885024de96b6ec73650c340c8928066585c413df", - "integrity": "sha512-srmJ1vWm8ZQTYflZCf7oUs3WBX83GyCIzsFUpwxUg2wcDHngSHjjShRTCgmkciPkVmM4aJ33i9baYS9jRC+zLA==", - "license": "MIT", - "dependencies": { - "@react-native-community/netinfo": "^4.1.3", - "redux-persist": "^4.5.0" - }, - "peerDependencies": { - "redux": ">=3" - } - }, - "node_modules/redux-offline/node_modules/redux-persist": { - "version": "4.10.2", - "resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-4.10.2.tgz", - "integrity": "sha512-U+e0ieMGC69Zr72929iJW40dEld7Mflh6mu0eJtVMLGfMq/aJqjxUM1hzyUWMR1VUyAEEdPHuQmeq5ti9krIgg==", - "dependencies": { - "json-stringify-safe": "^5.0.1", - "lodash": "^4.17.4", - "lodash-es": "^4.17.4" - } - }, "node_modules/redux-persist": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-6.0.0.tgz", @@ -26502,6 +26286,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/redux-persist-node-storage/-/redux-persist-node-storage-2.0.0.tgz", "integrity": "sha512-nytPz/iNTrAO4o8A17UaipPl8tVcrnm84r6v0tgHJ+q0ysEzyS/rBlPGXrKNIPplXi/W4riUTQlCIhajodIfJg==", + "dev": true, "dependencies": { "node-localstorage": "^1.3.0" } @@ -26695,28 +26480,6 @@ "node": "*" } }, - "node_modules/remote-redux-devtools": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/remote-redux-devtools/-/remote-redux-devtools-0.5.16.tgz", - "integrity": "sha512-xZ2D1VRIWzat5nsvcraT6fKEX9Cfi+HbQBCwzNnUAM8Uicm/anOc60XGalcaDPrVmLug7nhDl2nimEa3bL3K9w==", - "dependencies": { - "jsan": "^3.1.13", - "querystring": "^0.2.0", - "redux-devtools-core": "^0.2.1", - "redux-devtools-instrument": "^1.9.4", - "rn-host-detect": "^1.1.5", - "socketcluster-client": "^14.2.1" - } - }, - "node_modules/remotedev-serialize": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/remotedev-serialize/-/remotedev-serialize-0.1.9.tgz", - "integrity": "sha512-5tFdZg9mSaAWTv6xmQ7HtHjKMLSFQFExEZOtJe10PLsv1wb7cy7kYHtBvTYRro27/3fRGEcQBRNKSaixOpb69w==", - "deprecated": "Package moved to @redux-devtools/serialize.", - "dependencies": { - "jsan": "^3.1.13" - } - }, "node_modules/remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", @@ -27040,11 +26803,6 @@ "inherits": "^2.0.1" } }, - "node_modules/rn-host-detect": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/rn-host-detect/-/rn-host-detect-1.2.0.tgz", - "integrity": "sha512-btNg5kzHcjZZ7t7mvvV/4wNJ9e3MPgrWivkRgWURzXL0JJ0pwWlU4zrbmdlz3HHzHOxhBhHB4D+/dbMFfu4/4A==" - }, "node_modules/rollup": { "version": "2.79.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", @@ -27390,24 +27148,6 @@ "node": ">=10" } }, - "node_modules/sc-channel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/sc-channel/-/sc-channel-1.2.0.tgz", - "integrity": "sha512-M3gdq8PlKg0zWJSisWqAsMmTVxYRTpVRqw4CWAdKBgAfVKumFcTjoCV0hYu7lgUXccCtCD8Wk9VkkE+IXCxmZA==", - "dependencies": { - "component-emitter": "1.2.1" - } - }, - "node_modules/sc-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/sc-errors/-/sc-errors-2.0.1.tgz", - "integrity": "sha512-JoVhq3Ud+3Ujv2SIG7W0XtjRHsrNgl6iXuHHsh0s+Kdt5NwI6N2EGAZD4iteitdDv68ENBkpjtSvN597/wxPSQ==" - }, - "node_modules/sc-formatter": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/sc-formatter/-/sc-formatter-3.0.3.tgz", - "integrity": "sha512-lYI/lTs1u1c0geKElcj+bmEUfcP/HuKg2iDeTijPSjiTNFzN3Cf8Qh6tVd65oi7Qn+2/oD7LP4s6GC13v/9NiQ==" - }, "node_modules/scheduler": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", @@ -27901,6 +27641,7 @@ "version": "1.1.6", "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", "integrity": "sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw==", + "dev": true, "engines": { "node": "*" } @@ -27923,72 +27664,6 @@ "tslib": "^2.0.3" } }, - "node_modules/socketcluster-client": { - "version": "14.3.2", - "resolved": "https://registry.npmjs.org/socketcluster-client/-/socketcluster-client-14.3.2.tgz", - "integrity": "sha512-xDtgW7Ss0ARlfhx53bJ5GY5THDdEOeJnT+/C9Rmrj/vnZr54xeiQfrCZJbcglwe732nK3V+uZq87IvrRl7Hn4g==", - "dependencies": { - "buffer": "^5.2.1", - "clone": "2.1.1", - "component-emitter": "1.2.1", - "linked-list": "0.1.0", - "querystring": "0.2.0", - "sc-channel": "^1.2.0", - "sc-errors": "^2.0.1", - "sc-formatter": "^3.0.1", - "uuid": "3.2.1", - "ws": "^7.5.0" - } - }, - "node_modules/socketcluster-client/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/socketcluster-client/node_modules/clone": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", - "integrity": "sha512-h5FLmEMFHeuzqmpVRcDayNlVZ+k4uK1niyKQN6oUMe7ieJihv44Vc3dY/kDnnWX4PDQSwes48s965PG/D4GntQ==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/socketcluster-client/node_modules/querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", - "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/socketcluster-client/node_modules/uuid": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", - "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -31585,6 +31260,7 @@ "version": "7.5.9", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "dev": true, "engines": { "node": ">=8.3.0" }, @@ -39138,11 +38814,6 @@ "resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-2.0.0.tgz", "integrity": "sha512-Pc/AFTdwZwEKJxFJvlxrSmGe/di+aAOBn60sremrpLo6VI/6cmiUYNNwlI5KNYttg7uypzA3ILPMPgxB2GYZEg==" }, - "@react-native-community/netinfo": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@react-native-community/netinfo/-/netinfo-4.7.0.tgz", - "integrity": "sha512-a/sDB+AsLEUNmhAUlAaTYeXKyQdFGBUfatqKkX5jluBo2CB3OAuTHfm7rSjcaLB9EmG5iSq3fOTpync2E7EYTA==" - }, "@redux-devtools/extension": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/@redux-devtools/extension/-/extension-3.2.3.tgz", @@ -42299,7 +41970,6 @@ "jest-mock": "27.5.1", "lodash": "^4.17.21", "marked": "^4.0.12", - "mattermost-redux": "5.33.1", "mini-create-react-context": "^0.4.1", "moment": "^2.29.1", "nanoevents": "^5.1.13", @@ -44791,11 +44461,6 @@ "helpertypes": "^0.0.18" } }, - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha512-jPatnhd33viNplKjqXKRkGU345p263OIWzDL2wH3LGIGp5Kojo+uXizHmOADRvhGFFTnJqX3jBAKP6vvmSDKcA==" - }, "compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -48291,11 +47956,6 @@ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true }, - "get-params": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/get-params/-/get-params-0.1.2.tgz", - "integrity": "sha512-41eOxtlGgHQRbFyA8KTH+w+32Em3cRdfBud7j67ulzmIfmaHX9doq47s0fa4P5o9H64BZX9nrYI6sJvk46Op+Q==" - }, "get-proxy": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/get-proxy/-/get-proxy-2.1.0.tgz", @@ -49518,7 +49178,8 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==" + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true }, "indent-string": { "version": "4.0.0", @@ -51084,11 +50745,6 @@ "esprima": "^4.0.0" } }, - "jsan": { - "version": "3.1.14", - "resolved": "https://registry.npmjs.org/jsan/-/jsan-3.1.14.tgz", - "integrity": "sha512-wStfgOJqMv4QKktuH273f5fyi3D3vy2pHOiSDGPvpcS/q+wb/M7AK3vkCcaHbkZxDOlDU/lDJgccygKSG2OhtA==" - }, "jsdom": { "version": "16.7.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", @@ -51195,7 +50851,8 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true }, "json-to-pretty-yaml": { "version": "1.2.2", @@ -51367,11 +51024,6 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, - "linked-list": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/linked-list/-/linked-list-0.1.0.tgz", - "integrity": "sha512-Zr4ovrd0ODzF3ut2TWZMdHIxb8iFdJc/P3QM4iCJdlxxGHXo69c9hGIHzLo8/FtuR9E6WUZc5irKhtPUgOKMAg==" - }, "listr2": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.5.tgz", @@ -51771,105 +51423,6 @@ "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", "dev": true }, - "mattermost-redux": { - "version": "5.33.1", - "resolved": "https://registry.npmjs.org/mattermost-redux/-/mattermost-redux-5.33.1.tgz", - "integrity": "sha512-fHTW5PeB0xAE5u6uMds+hlWaJsUeWgE1034vekUah1X4bZCzBcMK4fM+ycGaIQ7c5Ylj9ML6Ni10XJYiQpMo5w==", - "requires": { - "core-js": "3.8.3", - "form-data": "3.0.0", - "gfycat-sdk": "1.4.18", - "moment-timezone": "0.5.32", - "redux": "4.0.5", - "redux-action-buffer": "1.2.0", - "redux-offline": "git+https://github.com/enahum/redux-offline.git#885024de96b6ec73650c340c8928066585c413df", - "redux-persist": "4.9.1", - "redux-persist-node-storage": "2.0.0", - "redux-thunk": "2.3.0", - "remote-redux-devtools": "0.5.16", - "reselect": "4.0.0", - "rudder-sdk-js": "1.0.14", - "serialize-error": "6.0.0", - "shallow-equals": "1.0.0" - }, - "dependencies": { - "core-js": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.8.3.tgz", - "integrity": "sha512-KPYXeVZYemC2TkNEkX/01I+7yd+nX3KddKwZ1Ww7SKWdI2wQprSgLmrTddT8nw92AjEklTsPBoSdQBhbI1bQ6Q==" - }, - "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==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "moment-timezone": { - "version": "0.5.32", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.32.tgz", - "integrity": "sha512-Z8QNyuQHQAmWucp8Knmgei8YNo28aLjJq6Ma+jy1ZSpSk5nyfRT8xgUbSQvD2+2UajISfenndwvFuH3NGS+nvA==", - "requires": { - "moment": ">= 2.9.0" - } - }, - "redux": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz", - "integrity": "sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==", - "requires": { - "loose-envify": "^1.4.0", - "symbol-observable": "^1.2.0" - } - }, - "redux-persist": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-4.9.1.tgz", - "integrity": "sha512-XoOmfPyo9GEU/WLH9FgB47dNIN9l5ArjHes4o7vUWx9nxZoPxnVodhuHdyc4Ot+fMkdj3L2LTqSHhwrkr0QFUg==", - "requires": { - "json-stringify-safe": "^5.0.1", - "lodash": "^4.17.4", - "lodash-es": "^4.17.4" - } - }, - "redux-thunk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz", - "integrity": "sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw==" - }, - "reselect": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.0.0.tgz", - "integrity": "sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA==" - }, - "rudder-sdk-js": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/rudder-sdk-js/-/rudder-sdk-js-1.0.14.tgz", - "integrity": "sha512-q86qmF6VUXjTUCv1YRFc2V1pt408D641nD2ymKFaLtGZTLjkZCzotQ7cW8c48vPKlSWwekkBlA3kghy/NKGwOw==" - }, - "serialize-error": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-6.0.0.tgz", - "integrity": "sha512-3vmBkMZLQO+BR4RPHcyRGdE09XCF6cvxzk2N2qn8Er3F91cy8Qt7VvEbZBOpaL53qsBbe2cFOefU6tRY6WDelA==", - "requires": { - "type-fest": "^0.12.0" - } - }, - "symbol-observable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" - }, - "type-fest": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.12.0.tgz", - "integrity": "sha512-53RyidyjvkGpnWPMF9bQgFtWp+Sl8O2Rp13VavmJgfAP9WWG6q6TkrKU8iyJdnwnfgHI6k2hTlgqH4aSdjoTbg==" - } - } - }, "mattermost-webapp": { "version": "file:channels", "requires": { @@ -52791,6 +52344,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-localstorage/-/node-localstorage-1.3.1.tgz", "integrity": "sha512-NMWCSWWc6JbHT5PyWlNT2i8r7PgGYXVntmKawY83k/M0UJScZ5jirb61TLnqKwd815DfBQu+lR3sRw08SPzIaQ==", + "dev": true, "requires": { "write-file-atomic": "^1.1.4" }, @@ -52799,6 +52353,7 @@ "version": "1.3.4", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", "integrity": "sha512-SdrHoC/yVBPpV0Xq/mUZQIpW2sWXAShb/V4pomcJXh92RuaO+f3UTWItiR3Px+pLnV2PvC2/bfn5cwr5X6Vfxw==", + "dev": true, "requires": { "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", @@ -56013,7 +55568,8 @@ "querystring": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz", - "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==" + "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==", + "dev": true }, "querystringify": { "version": "2.2.0", @@ -56755,51 +56311,11 @@ "@babel/runtime": "^7.9.2" } }, - "redux-action-buffer": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/redux-action-buffer/-/redux-action-buffer-1.2.0.tgz", - "integrity": "sha512-SvXSJQrn1Nsmza+xVMlvqZf0eiHIPV3I796jVC2DCC8X8+JXpAaSFuNxlxV0Cn+TAilat7KZ3srTwG5+HHL8tw==" - }, "redux-batched-actions": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/redux-batched-actions/-/redux-batched-actions-0.5.0.tgz", "integrity": "sha512-6orZWyCnIQXMGY4DUGM0oj0L7oYnwTACsfsru/J7r94RM3P9eS7SORGpr3LCeRCMoIMQcpfKZ7X4NdyFHBS8Eg==" }, - "redux-devtools-core": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/redux-devtools-core/-/redux-devtools-core-0.2.1.tgz", - "integrity": "sha512-RAGOxtUFdr/1USAvxrWd+Gq/Euzgw7quCZlO5TgFpDfG7rB5tMhZUrNyBjpzgzL2yMk0eHnPYIGm7NkIfRzHxQ==", - "requires": { - "get-params": "^0.1.2", - "jsan": "^3.1.13", - "lodash": "^4.17.11", - "nanoid": "^2.0.0", - "remotedev-serialize": "^0.1.8" - }, - "dependencies": { - "nanoid": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz", - "integrity": "sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==" - } - } - }, - "redux-devtools-instrument": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/redux-devtools-instrument/-/redux-devtools-instrument-1.10.0.tgz", - "integrity": "sha512-X8JRBCzX2ADSMp+iiV7YQ8uoTNyEm0VPFPd4T854coz6lvRiBrFSqAr9YAS2n8Kzxx8CJQotR0QF9wsMM+3DvA==", - "requires": { - "lodash": "^4.17.19", - "symbol-observable": "^1.2.0" - }, - "dependencies": { - "symbol-observable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" - } - } - }, "redux-mock-store": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/redux-mock-store/-/redux-mock-store-1.5.4.tgz", @@ -56809,27 +56325,6 @@ "lodash.isplainobject": "^4.0.6" } }, - "redux-offline": { - "version": "git+ssh://git@github.com/enahum/redux-offline.git#885024de96b6ec73650c340c8928066585c413df", - "integrity": "sha512-srmJ1vWm8ZQTYflZCf7oUs3WBX83GyCIzsFUpwxUg2wcDHngSHjjShRTCgmkciPkVmM4aJ33i9baYS9jRC+zLA==", - "from": "redux-offline@git+https://github.com/enahum/redux-offline.git#885024de96b6ec73650c340c8928066585c413df", - "requires": { - "@react-native-community/netinfo": "^4.1.3", - "redux-persist": "^4.5.0" - }, - "dependencies": { - "redux-persist": { - "version": "4.10.2", - "resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-4.10.2.tgz", - "integrity": "sha512-U+e0ieMGC69Zr72929iJW40dEld7Mflh6mu0eJtVMLGfMq/aJqjxUM1hzyUWMR1VUyAEEdPHuQmeq5ti9krIgg==", - "requires": { - "json-stringify-safe": "^5.0.1", - "lodash": "^4.17.4", - "lodash-es": "^4.17.4" - } - } - } - }, "redux-persist": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-6.0.0.tgz", @@ -56839,6 +56334,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/redux-persist-node-storage/-/redux-persist-node-storage-2.0.0.tgz", "integrity": "sha512-nytPz/iNTrAO4o8A17UaipPl8tVcrnm84r6v0tgHJ+q0ysEzyS/rBlPGXrKNIPplXi/W4riUTQlCIhajodIfJg==", + "dev": true, "requires": { "node-localstorage": "^1.3.0" } @@ -56989,27 +56485,6 @@ "integrity": "sha512-/62tYiOe6DzS5BqVsNpH/nkGlX45C/Sp6V+NtiN6JQNS1Viay7cWkazmRkrQrdFj2eshDe96SIQNIoMxqhzBOg==", "dev": true }, - "remote-redux-devtools": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/remote-redux-devtools/-/remote-redux-devtools-0.5.16.tgz", - "integrity": "sha512-xZ2D1VRIWzat5nsvcraT6fKEX9Cfi+HbQBCwzNnUAM8Uicm/anOc60XGalcaDPrVmLug7nhDl2nimEa3bL3K9w==", - "requires": { - "jsan": "^3.1.13", - "querystring": "^0.2.0", - "redux-devtools-core": "^0.2.1", - "redux-devtools-instrument": "^1.9.4", - "rn-host-detect": "^1.1.5", - "socketcluster-client": "^14.2.1" - } - }, - "remotedev-serialize": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/remotedev-serialize/-/remotedev-serialize-0.1.9.tgz", - "integrity": "sha512-5tFdZg9mSaAWTv6xmQ7HtHjKMLSFQFExEZOtJe10PLsv1wb7cy7kYHtBvTYRro27/3fRGEcQBRNKSaixOpb69w==", - "requires": { - "jsan": "^3.1.13" - } - }, "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", @@ -57260,11 +56735,6 @@ "inherits": "^2.0.1" } }, - "rn-host-detect": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/rn-host-detect/-/rn-host-detect-1.2.0.tgz", - "integrity": "sha512-btNg5kzHcjZZ7t7mvvV/4wNJ9e3MPgrWivkRgWURzXL0JJ0pwWlU4zrbmdlz3HHzHOxhBhHB4D+/dbMFfu4/4A==" - }, "rollup": { "version": "2.79.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", @@ -57480,24 +56950,6 @@ "xmlchars": "^2.2.0" } }, - "sc-channel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/sc-channel/-/sc-channel-1.2.0.tgz", - "integrity": "sha512-M3gdq8PlKg0zWJSisWqAsMmTVxYRTpVRqw4CWAdKBgAfVKumFcTjoCV0hYu7lgUXccCtCD8Wk9VkkE+IXCxmZA==", - "requires": { - "component-emitter": "1.2.1" - } - }, - "sc-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/sc-errors/-/sc-errors-2.0.1.tgz", - "integrity": "sha512-JoVhq3Ud+3Ujv2SIG7W0XtjRHsrNgl6iXuHHsh0s+Kdt5NwI6N2EGAZD4iteitdDv68ENBkpjtSvN597/wxPSQ==" - }, - "sc-formatter": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/sc-formatter/-/sc-formatter-3.0.3.tgz", - "integrity": "sha512-lYI/lTs1u1c0geKElcj+bmEUfcP/HuKg2iDeTijPSjiTNFzN3Cf8Qh6tVd65oi7Qn+2/oD7LP4s6GC13v/9NiQ==" - }, "scheduler": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", @@ -57906,7 +57358,8 @@ "slide": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", - "integrity": "sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw==" + "integrity": "sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw==", + "dev": true }, "smooth-scroll-into-view-if-needed": { "version": "1.1.33", @@ -57926,49 +57379,6 @@ "tslib": "^2.0.3" } }, - "socketcluster-client": { - "version": "14.3.2", - "resolved": "https://registry.npmjs.org/socketcluster-client/-/socketcluster-client-14.3.2.tgz", - "integrity": "sha512-xDtgW7Ss0ARlfhx53bJ5GY5THDdEOeJnT+/C9Rmrj/vnZr54xeiQfrCZJbcglwe732nK3V+uZq87IvrRl7Hn4g==", - "requires": { - "buffer": "^5.2.1", - "clone": "2.1.1", - "component-emitter": "1.2.1", - "linked-list": "0.1.0", - "querystring": "0.2.0", - "sc-channel": "^1.2.0", - "sc-errors": "^2.0.1", - "sc-formatter": "^3.0.1", - "uuid": "3.2.1", - "ws": "^7.5.0" - }, - "dependencies": { - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "clone": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", - "integrity": "sha512-h5FLmEMFHeuzqmpVRcDayNlVZ+k4uK1niyKQN6oUMe7ieJihv44Vc3dY/kDnnWX4PDQSwes48s965PG/D4GntQ==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==" - }, - "uuid": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", - "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==" - } - } - }, "sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -60705,7 +60115,8 @@ "ws": { "version": "7.5.9", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==" + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "dev": true }, "xhr": { "version": "2.6.0", diff --git a/webapp/playbooks/jest.config.js b/webapp/playbooks/jest.config.js index 1c9eae985f..209ee1b2db 100644 --- a/webapp/playbooks/jest.config.js +++ b/webapp/playbooks/jest.config.js @@ -9,6 +9,7 @@ const config = { '^@mattermost/(components)$': '/../platform/$1/src', '^@mattermost/(client)$': '/../platform/$1/src', '^@mattermost/(types)/(.*)$': '/../platform/$1/src/$2', + '^mattermost-redux/(.*)$': '/../channels/src/packages/mattermost-redux/src/$1', '^reselect$': '/../channels/src/packages/reselect/src', '^src/(.*)$': '/src/$1', }, From a25a3826baa8056f65ac5956d38824a0a5efcd6a Mon Sep 17 00:00:00 2001 From: Harrison Healey Date: Tue, 28 Mar 2023 15:36:52 -0400 Subject: [PATCH 38/46] MM-51729 Fix make dev after monorepo move (#22687) --- webapp/scripts/dev-server.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/webapp/scripts/dev-server.js b/webapp/scripts/dev-server.js index 2b47292834..c279c36cdf 100644 --- a/webapp/scripts/dev-server.js +++ b/webapp/scripts/dev-server.js @@ -6,18 +6,18 @@ const chalk = require('chalk'); const concurrently = require('concurrently'); -const {getWorkspaceCommands} = require('./utils.js'); +const {getPlatformCommands} = require('./utils.js'); async function watchAllWithDevServer() { console.log(chalk.inverse.bold('Watching web app and all subpackages...')); const commands = [ - {command: 'npm:dev-server:webapp', name: 'webapp', prefixColor: 'cyan'}, + {command: 'npm:dev-server --workspace=channels', name: 'webapp', prefixColor: 'cyan'}, {command: 'npm:start:product --workspace=boards', name: 'boards', prefixColor: 'blue'}, {command: 'npm:start:product --workspace=playbooks', name: 'playbooks', prefixColor: 'red'}, ]; - commands.push(...getWorkspaceCommands('run')); + commands.push(...getPlatformCommands('run')); console.log('\n'); From 932790f99ae82a4fdf488ce6dcdf1534ed592b2e Mon Sep 17 00:00:00 2001 From: Scott Bishel Date: Tue, 28 Mar 2023 14:49:12 -0600 Subject: [PATCH 39/46] fix issue with card id being valid block but not card (#22697) --- .../__snapshots__/boardsUnfurl.test.tsx.snap | 6 + .../boardsUnfurl/boardsUnfurl.test.tsx | 115 ++++++++++++++++++ .../components/boardsUnfurl/boardsUnfurl.tsx | 4 +- 3 files changed, 123 insertions(+), 2 deletions(-) diff --git a/webapp/boards/src/components/boardsUnfurl/__snapshots__/boardsUnfurl.test.tsx.snap b/webapp/boards/src/components/boardsUnfurl/__snapshots__/boardsUnfurl.test.tsx.snap index bbf4ddc411..cfe233747c 100644 --- a/webapp/boards/src/components/boardsUnfurl/__snapshots__/boardsUnfurl.test.tsx.snap +++ b/webapp/boards/src/components/boardsUnfurl/__snapshots__/boardsUnfurl.test.tsx.snap @@ -96,3 +96,9 @@ exports[`components/boardsUnfurl/BoardsUnfurl renders when limited 1`] = `
  • `; + +exports[`components/boardsUnfurl/BoardsUnfurl test invalid card, invalid block 1`] = `
    `; + +exports[`components/boardsUnfurl/BoardsUnfurl test invalid card, valid block 1`] = `
    `; + +exports[`components/boardsUnfurl/BoardsUnfurl test no card 1`] = `
    `; diff --git a/webapp/boards/src/components/boardsUnfurl/boardsUnfurl.test.tsx b/webapp/boards/src/components/boardsUnfurl/boardsUnfurl.test.tsx index 81b11ae171..6afe19042b 100644 --- a/webapp/boards/src/components/boardsUnfurl/boardsUnfurl.test.tsx +++ b/webapp/boards/src/components/boardsUnfurl/boardsUnfurl.test.tsx @@ -16,6 +16,8 @@ import {createBoard} from 'src/blocks/board' import octoClient from 'src/octoClient' import {wrapIntl} from 'src/testUtils' +import {createBoardView} from 'src/blocks/boardView' + import BoardsUnfurl from './boardsUnfurl' jest.mock('src/octoClient') @@ -114,5 +116,118 @@ describe('components/boardsUnfurl/BoardsUnfurl', () => { expect(container).toMatchSnapshot() }) + + it('test no card', async () => { + const mockStore = configureStore([]) + const store = mockStore({ + language: { + value: 'en', + }, + teams: { + allTeams: [team], + current: team, + }, + }) + + const board = {...createBoard(), title: 'test board'} + // mockedOctoClient.getBoard.mockResolvedValueOnce(board) + + const component = ( + + {wrapIntl( + , + )} + + ) + + let container: Element | DocumentFragment | null = null + + await act(async () => { + const result = render(component) + container = result.container + }) + expect(container).toMatchSnapshot() + }) + + it('test invalid card, valid block', async () => { + const mockStore = configureStore([]) + const store = mockStore({ + language: { + value: 'en', + }, + teams: { + allTeams: [team], + current: team, + }, + }) + + const cards = [{...createBoardView(), title: 'test view', updateAt: 12345}] + const board = {...createBoard(), title: 'test board'} + + mockedOctoClient.getBlocksWithBlockID.mockResolvedValueOnce(cards) + mockedOctoClient.getBoard.mockResolvedValueOnce(board) + + const component = ( + + {wrapIntl( + , + )} + + ) + + let container: Element | DocumentFragment | null = null + + await act(async () => { + const result = render(component) + container = result.container + }) + expect(mockedOctoClient.getBoard).toBeCalledWith(board.id) + expect(mockedOctoClient.getBlocksWithBlockID).toBeCalledWith(cards[0].id, board.id, 'abc') + + expect(container).toMatchSnapshot() + }) + + it('test invalid card, invalid block', async () => { + const mockStore = configureStore([]) + const store = mockStore({ + language: { + value: 'en', + }, + teams: { + allTeams: [team], + current: team, + }, + }) + + const board = {...createBoard(), title: 'test board'} + + mockedOctoClient.getBlocksWithBlockID.mockResolvedValueOnce([]) + mockedOctoClient.getBoard.mockResolvedValueOnce(board) + + const component = ( + + {wrapIntl( + , + )} + + ) + + let container: Element | DocumentFragment | null = null + + await act(async () => { + const result = render(component) + container = result.container + }) + expect(mockedOctoClient.getBoard).toBeCalledWith(board.id) + expect(mockedOctoClient.getBlocksWithBlockID).toBeCalledWith('invalidCard', board.id, 'abc') + + expect(container).toMatchSnapshot() + }) }) diff --git a/webapp/boards/src/components/boardsUnfurl/boardsUnfurl.tsx b/webapp/boards/src/components/boardsUnfurl/boardsUnfurl.tsx index dcb741b591..08a9f5eb51 100644 --- a/webapp/boards/src/components/boardsUnfurl/boardsUnfurl.tsx +++ b/webapp/boards/src/components/boardsUnfurl/boardsUnfurl.tsx @@ -84,7 +84,7 @@ export const BoardsUnfurl = (props: Props): JSX.Element => { ], ) const [firstCard] = cards as Card[] - if (!firstCard || !fetchedBoard) { + if (!firstCard || !fetchedBoard || firstCard.type !== 'card') { setLoading(false) return null } @@ -116,7 +116,7 @@ export const BoardsUnfurl = (props: Props): JSX.Element => { useWebsockets(currentTeamId, (wsClient: WSClient) => { const onChangeHandler = (_: WSClient, blocks: Block[]): void => { const cardBlock: Block|undefined = blocks.find((b) => b.id === cardID) - if (cardBlock && !cardBlock.deleteAt) { + if (cardBlock && !cardBlock.deleteAt && cardBlock.type === 'card') { setCard(cardBlock as Card) } From 529ab959e26b7e5507bd345f271bea9b86219432 Mon Sep 17 00:00:00 2001 From: Ashish Dhama <16203333+AshishDhama@users.noreply.github.com> Date: Wed, 29 Mar 2023 10:48:32 +0530 Subject: [PATCH 40/46] exclude file count on channel stats api call on from channel header (#22624) --- .../channels/src/actions/global_actions.tsx | 2 +- .../channel_info_rhs.test.tsx | 18 +++++-- .../channel_info_rhs/channel_info_rhs.tsx | 2 + .../src/components/channel_info_rhs/index.ts | 3 +- .../components/channel_info_rhs/menu.test.tsx | 49 +++++++++++++++---- .../src/components/channel_info_rhs/menu.tsx | 23 +++++++-- .../mattermost-redux/src/actions/channels.ts | 12 +++-- webapp/platform/client/src/client4.ts | 5 +- 8 files changed, 90 insertions(+), 24 deletions(-) diff --git a/webapp/channels/src/actions/global_actions.tsx b/webapp/channels/src/actions/global_actions.tsx index aa18c5a89e..cb22542fa4 100644 --- a/webapp/channels/src/actions/global_actions.tsx +++ b/webapp/channels/src/actions/global_actions.tsx @@ -65,7 +65,7 @@ export function emitChannelClickEvent(channel: Channel) { const currentChannelId = getCurrentChannelId(state); const previousRhsState = getPreviousRhsState(state); - dispatch(getChannelStats(chan.id)); + dispatch(getChannelStats(chan.id, true)); const penultimate = LocalStorageStore.getPreviousChannelName(userId, teamId); const penultimateType = LocalStorageStore.getPreviousViewedType(userId, teamId); diff --git a/webapp/channels/src/components/channel_info_rhs/channel_info_rhs.test.tsx b/webapp/channels/src/components/channel_info_rhs/channel_info_rhs.test.tsx index a9de0e72fd..4babb664d7 100644 --- a/webapp/channels/src/components/channel_info_rhs/channel_info_rhs.test.tsx +++ b/webapp/channels/src/components/channel_info_rhs/channel_info_rhs.test.tsx @@ -3,8 +3,11 @@ import React from 'react'; -import {Channel, ChannelStats} from '@mattermost/types/channels'; +import {act} from '@testing-library/react'; + import {renderWithIntl} from 'tests/react_testing_utils'; + +import {Channel, ChannelStats} from '@mattermost/types/channels'; import {UserProfile} from '@mattermost/types/users'; import {Team} from '@mattermost/types/teams'; @@ -40,6 +43,7 @@ describe('channel_info_rhs', () => { showChannelFiles: jest.fn(), showPinnedPosts: jest.fn(), showChannelMembers: jest.fn(), + getChannelStats: jest.fn().mockImplementation(() => Promise.resolve({data: {}})), }, }; let props = {...OriginalProps}; @@ -49,20 +53,24 @@ describe('channel_info_rhs', () => { }); describe('about area', () => { - test('should be editable', () => { + test('should be editable', async () => { renderWithIntl( , ); + await act(async () => { + props.actions.getChannelStats(); + }); + expect(mockAboutArea).toHaveBeenCalledWith( expect.objectContaining({ canEditChannelProperties: true, }), ); }); - test('should not be editable in archived channel', () => { + test('should not be editable in archived channel', async () => { props.isArchived = true; renderWithIntl( @@ -71,6 +79,10 @@ describe('channel_info_rhs', () => { />, ); + await act(async () => { + props.actions.getChannelStats(); + }); + expect(mockAboutArea).toHaveBeenCalledWith( expect.objectContaining({ canEditChannelProperties: false, diff --git a/webapp/channels/src/components/channel_info_rhs/channel_info_rhs.tsx b/webapp/channels/src/components/channel_info_rhs/channel_info_rhs.tsx index f16b9c77ea..7f75970911 100644 --- a/webapp/channels/src/components/channel_info_rhs/channel_info_rhs.tsx +++ b/webapp/channels/src/components/channel_info_rhs/channel_info_rhs.tsx @@ -64,6 +64,7 @@ export interface Props { showChannelFiles: (channelId: string) => void; showPinnedPosts: (channelId: string | undefined) => void; showChannelMembers: (channelId: string) => void; + getChannelStats: (channelId: string) => Promise<{data: ChannelStats}>; }; } @@ -192,6 +193,7 @@ const ChannelInfoRhs = ({ showChannelFiles: actions.showChannelFiles, showPinnedPosts: actions.showPinnedPosts, showChannelMembers: actions.showChannelMembers, + getChannelStats: actions.getChannelStats, }} />
    diff --git a/webapp/channels/src/components/channel_info_rhs/index.ts b/webapp/channels/src/components/channel_info_rhs/index.ts index 09d6e8e49d..f30d8ebb8b 100644 --- a/webapp/channels/src/components/channel_info_rhs/index.ts +++ b/webapp/channels/src/components/channel_info_rhs/index.ts @@ -16,7 +16,7 @@ import {Constants, ModalIdentifiers} from 'utils/constants'; import {getCurrentUser} from 'mattermost-redux/selectors/entities/common'; import {getIsMobileView} from 'selectors/views/browser'; import {getCurrentTeam} from 'mattermost-redux/selectors/entities/teams'; -import {unfavoriteChannel, favoriteChannel} from 'mattermost-redux/actions/channels'; +import {unfavoriteChannel, favoriteChannel, getChannelStats} from 'mattermost-redux/actions/channels'; import {muteChannel, unmuteChannel} from 'actions/channel_actions'; import {openModal} from 'actions/views/modals'; import {getDisplayNameByUser, getUserIdFromChannelId} from 'utils/utils'; @@ -92,6 +92,7 @@ function mapDispatchToProps(dispatch: Dispatch) { showChannelFiles, showPinnedPosts, showChannelMembers, + getChannelStats, }, dispatch), }; } diff --git a/webapp/channels/src/components/channel_info_rhs/menu.test.tsx b/webapp/channels/src/components/channel_info_rhs/menu.test.tsx index 1e4a8d5537..d68f9a2392 100644 --- a/webapp/channels/src/components/channel_info_rhs/menu.test.tsx +++ b/webapp/channels/src/components/channel_info_rhs/menu.test.tsx @@ -2,12 +2,13 @@ // See LICENSE.txt for license information. import React from 'react'; -import {fireEvent, screen} from '@testing-library/react'; +import {act, fireEvent, screen} from '@testing-library/react'; -import {Channel, ChannelStats} from '@mattermost/types/channels'; import {renderWithIntl} from 'tests/react_testing_utils'; import Constants from 'utils/constants'; +import {Channel, ChannelStats} from '@mattermost/types/channels'; + import Menu from './menu'; describe('channel_info_rhs/menu', () => { @@ -20,6 +21,7 @@ describe('channel_info_rhs/menu', () => { showChannelFiles: jest.fn(), showPinnedPosts: jest.fn(), showChannelMembers: jest.fn(), + getChannelStats: jest.fn().mockImplementation(() => Promise.resolve({data: {files_count: 3, pinnedpost_count: 12, member_count: 32}})), }, }; @@ -29,10 +31,11 @@ describe('channel_info_rhs/menu', () => { showChannelFiles: jest.fn(), showPinnedPosts: jest.fn(), showChannelMembers: jest.fn(), + getChannelStats: jest.fn().mockImplementation(() => Promise.resolve({data: {files_count: 3, pinnedpost_count: 12, member_count: 32}})), }; }); - test('should display notifications preferences', () => { + test('should display notifications preferences', async () => { const props = {...defaultProps}; props.actions.openNotificationSettings = jest.fn(); @@ -42,13 +45,17 @@ describe('channel_info_rhs/menu', () => { />, ); + await act(async () => { + props.actions.getChannelStats(); + }); + expect(screen.getByText('Notification Preferences')).toBeInTheDocument(); fireEvent.click(screen.getByText('Notification Preferences')); expect(props.actions.openNotificationSettings).toHaveBeenCalled(); }); - test('should NOT display notifications preferences in a DM', () => { + test('should NOT display notifications preferences in a DM', async () => { const props = { ...defaultProps, channel: {type: Constants.DM_CHANNEL} as Channel, @@ -60,10 +67,14 @@ describe('channel_info_rhs/menu', () => { />, ); + await act(async () => { + props.actions.getChannelStats(); + }); + expect(screen.queryByText('Notification Preferences')).not.toBeInTheDocument(); }); - test('should NOT display notifications preferences in an archived channel', () => { + test('should NOT display notifications preferences in an archived channel', async () => { const props = { ...defaultProps, isArchived: true, @@ -75,10 +86,14 @@ describe('channel_info_rhs/menu', () => { />, ); + await act(async () => { + props.actions.getChannelStats(); + }); + expect(screen.queryByText('Notification Preferences')).not.toBeInTheDocument(); }); - test('should display the number of files', () => { + test('should display the number of files', async () => { const props = {...defaultProps}; props.actions.showChannelFiles = jest.fn(); @@ -88,6 +103,10 @@ describe('channel_info_rhs/menu', () => { />, ); + await act(async () => { + props.actions.getChannelStats(); + }); + const fileItem = screen.getByText('Files'); expect(fileItem).toBeInTheDocument(); expect(fileItem.parentElement).toHaveTextContent('3'); @@ -96,7 +115,7 @@ describe('channel_info_rhs/menu', () => { expect(props.actions.showChannelFiles).toHaveBeenCalled(); }); - test('should display the pinned messages', () => { + test('should display the pinned messages', async () => { const props = {...defaultProps}; props.actions.showPinnedPosts = jest.fn(); @@ -106,6 +125,10 @@ describe('channel_info_rhs/menu', () => { />, ); + await act(async () => { + props.actions.getChannelStats(); + }); + const fileItem = screen.getByText('Pinned Messages'); expect(fileItem).toBeInTheDocument(); expect(fileItem.parentElement).toHaveTextContent('12'); @@ -114,7 +137,7 @@ describe('channel_info_rhs/menu', () => { expect(props.actions.showPinnedPosts).toHaveBeenCalled(); }); - test('should display members', () => { + test('should display members', async () => { const props = {...defaultProps}; props.actions.showChannelMembers = jest.fn(); @@ -124,6 +147,10 @@ describe('channel_info_rhs/menu', () => { />, ); + await act(async () => { + props.actions.getChannelStats(); + }); + const membersItem = screen.getByText('Members'); expect(membersItem).toBeInTheDocument(); expect(membersItem.parentElement).toHaveTextContent('32'); @@ -132,7 +159,7 @@ describe('channel_info_rhs/menu', () => { expect(props.actions.showChannelMembers).toHaveBeenCalled(); }); - test('should NOT display members in DM', () => { + test('should NOT display members in DM', async () => { const props = { ...defaultProps, channel: {type: Constants.DM_CHANNEL} as Channel, @@ -144,6 +171,10 @@ describe('channel_info_rhs/menu', () => { />, ); + await act(async () => { + props.actions.getChannelStats(); + }); + const membersItem = screen.queryByText('Members'); expect(membersItem).not.toBeInTheDocument(); }); diff --git a/webapp/channels/src/components/channel_info_rhs/menu.tsx b/webapp/channels/src/components/channel_info_rhs/menu.tsx index 1092294e72..a45657c319 100644 --- a/webapp/channels/src/components/channel_info_rhs/menu.tsx +++ b/webapp/channels/src/components/channel_info_rhs/menu.tsx @@ -1,12 +1,14 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React from 'react'; +import React, {useEffect, useState} from 'react'; import styled from 'styled-components'; import {useIntl} from 'react-intl'; import {Constants} from 'utils/constants'; +import LoadingSpinner from 'components/widgets/loading/loading_spinner'; + import {Channel, ChannelStats} from '@mattermost/types/channels'; const MenuItemContainer = styled.div` @@ -32,6 +34,9 @@ const RightSide = styled.div` const Badge = styled.div` font-size: 12px; line-height: 18px; + width: 20px; + display: flex; + place-content: center; `; interface MenuItemProps { @@ -39,7 +44,7 @@ interface MenuItemProps { icon: JSX.Element; text: string; opensSubpanel?: boolean; - badge?: string|number; + badge?: string|number|JSX.Element; onClick: () => void; } @@ -94,14 +99,26 @@ interface MenuProps { showChannelFiles: (channelId: string) => void; showPinnedPosts: (channelId: string | undefined) => void; showChannelMembers: (channelId: string) => void; + getChannelStats: (channelId: string) => Promise<{data: ChannelStats}>; }; } const Menu = ({channel, channelStats, isArchived, className, actions}: MenuProps) => { const {formatMessage} = useIntl(); + const [loadingStats, setLoadingStats] = useState(true); const showNotificationPreferences = channel.type !== Constants.DM_CHANNEL && !isArchived; const showMembers = channel.type !== Constants.DM_CHANNEL; + const fileCount = channelStats?.files_count >= 0 ? channelStats?.files_count : 0; + + useEffect(() => { + actions.getChannelStats(channel.id).then(() => { + setLoadingStats(false); + }); + return () => { + setLoadingStats(true); + }; + }, [channel.id]); return (
    } text={formatMessage({id: 'channel_info_rhs.menu.files', defaultMessage: 'Files'})} opensSubpanel={true} - badge={channelStats?.files_count} + badge={loadingStats ? : fileCount} onClick={() => actions.showChannelFiles(channel.id)} />
    diff --git a/webapp/channels/src/packages/mattermost-redux/src/actions/channels.ts b/webapp/channels/src/packages/mattermost-redux/src/actions/channels.ts index 29e07bd064..f5afb85aa2 100644 --- a/webapp/channels/src/packages/mattermost-redux/src/actions/channels.ts +++ b/webapp/channels/src/packages/mattermost-redux/src/actions/channels.ts @@ -8,7 +8,6 @@ import {ChannelTypes, PreferenceTypes, UserTypes} from 'mattermost-redux/action_ import {Client4} from 'mattermost-redux/client'; -import {General, Preferences} from '../constants'; import {CategoryTypes} from 'mattermost-redux/constants/channel_categories'; import {MarkUnread} from 'mattermost-redux/constants/channels'; @@ -25,12 +24,15 @@ import {getCurrentTeamId} from 'mattermost-redux/selectors/entities/teams'; import {ActionFunc, ActionResult, DispatchFunc, GetStateFunc} from 'mattermost-redux/types/actions'; +import {getChannelsIdForTeam, getChannelByName} from 'mattermost-redux/utils/channel_utils'; + +import {isMinimumServerVersion} from 'mattermost-redux/utils/helpers'; + import {Channel, ChannelNotifyProps, ChannelMembership, ChannelModerationPatch, ChannelsWithTotalCount, ChannelSearchOpts} from '@mattermost/types/channels'; import {PreferenceType} from '@mattermost/types/preferences'; -import {getChannelsIdForTeam, getChannelByName} from 'mattermost-redux/utils/channel_utils'; -import {isMinimumServerVersion} from 'mattermost-redux/utils/helpers'; +import {General, Preferences} from '../constants'; import {addChannelToInitialCategory, addChannelToCategory} from './channel_categories'; import {logError} from './errors'; @@ -1074,11 +1076,11 @@ export function searchGroupChannels(term: string): ActionFunc { }); } -export function getChannelStats(channelId: string): ActionFunc { +export function getChannelStats(channelId: string, excludeFilesCount?: boolean): ActionFunc { return async (dispatch: DispatchFunc, getState: GetStateFunc) => { let stat; try { - stat = await Client4.getChannelStats(channelId); + stat = await Client4.getChannelStats(channelId, excludeFilesCount); } catch (error) { forceLogoutIfNecessary(error, dispatch, getState); dispatch(logError(error)); diff --git a/webapp/platform/client/src/client4.ts b/webapp/platform/client/src/client4.ts index 56e2f552f1..21a1a8798f 100644 --- a/webapp/platform/client/src/client4.ts +++ b/webapp/platform/client/src/client4.ts @@ -1782,9 +1782,10 @@ export default class Client4 { ); }; - getChannelStats = (channelId: string) => { + getChannelStats = (channelId: string, excludeFilesCount = false) => { + const param = excludeFilesCount ? `?exclude_files_count=${excludeFilesCount}` : ''; return this.doFetch( - `${this.getChannelRoute(channelId)}/stats`, + `${this.getChannelRoute(channelId)}/stats${param}`, {method: 'get'}, ); }; From 6bdadc246c3dc21e111842d8107eb95408e4782b Mon Sep 17 00:00:00 2001 From: Eva Sarafianou Date: Tue, 28 Mar 2023 15:13:40 +0200 Subject: [PATCH 41/46] Update codeql config for monorepo --- .github/workflows/codeql-analysis.yml | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 67779d669b..a023ecd86f 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -10,7 +10,7 @@ on: branches: [ master ] schedule: - cron: '30 5,17 * * *' - + permissions: contents: read @@ -24,7 +24,7 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'go' ] + language: [ 'go', 'javascript' ] steps: - name: Checkout repository @@ -36,14 +36,26 @@ jobs: with: languages: ${{ matrix.language }} debug: false - config-file: ./.github/codeql/codeql-config.yml - - - name: Build + config-file: ./.github/codeql/codeql-config.yml + + - name: Build JavaScript + uses: github/codeql-action/autobuild@v2 + if: ${{ matrix.language == 'javascript' }} + + - name: Setup go + uses: actions/setup-go@v2 + with: + go-version: '1.20' + if: ${{ matrix.language == 'go' }} + + + - name: Build Golang run: | cd server make setup-go-work make build-linux-amd64 + if: ${{ matrix.language == 'go' }} # Perform Analysis - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v2 From b892fe0555ede73f08e48ec8b31b268993fbe7d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Andr=C3=A9s=20V=C3=A9lez=20Vidal?= Date: Wed, 29 Mar 2023 13:39:27 +0200 Subject: [PATCH 42/46] MM-49865 - add telemetry to account creation screen (#22702) * MM-49865 - add telemetry to account creation screen * fix snapshots --- .../signup/__snapshots__/signup.test.tsx.snap | 6 +++ .../channels/src/components/signup/signup.tsx | 50 +++++++++++++++---- webapp/channels/src/utils/utils.tsx | 15 +++++- 3 files changed, 60 insertions(+), 11 deletions(-) diff --git a/webapp/channels/src/components/signup/__snapshots__/signup.test.tsx.snap b/webapp/channels/src/components/signup/__snapshots__/signup.test.tsx.snap index 78d02de456..691b7341e9 100644 --- a/webapp/channels/src/components/signup/__snapshots__/signup.test.tsx.snap +++ b/webapp/channels/src/components/signup/__snapshots__/signup.test.tsx.snap @@ -58,6 +58,7 @@ exports[`components/signup/Signup should match snapshot for all signup options e disabled={false} inputSize="large" name="email" + onBlur={[Function]} onChange={[Function]} placeholder="Email address" type="text" @@ -75,6 +76,7 @@ exports[`components/signup/Signup should match snapshot for all signup options e disabled={false} inputSize="large" name="name" + onBlur={[Function]} onChange={[Function]} placeholder="Choose a Username" type="text" @@ -87,6 +89,7 @@ exports[`components/signup/Signup should match snapshot for all signup options e error="" info="Must be 5-64 characters long." inputSize="large" + onBlur={[Function]} onChange={[Function]} value="" /> @@ -206,6 +209,7 @@ exports[`components/signup/Signup should match snapshot for all signup options e disabled={false} inputSize="large" name="email" + onBlur={[Function]} onChange={[Function]} placeholder="Email address" type="text" @@ -223,6 +227,7 @@ exports[`components/signup/Signup should match snapshot for all signup options e disabled={false} inputSize="large" name="name" + onBlur={[Function]} onChange={[Function]} placeholder="Choose a Username" type="text" @@ -235,6 +240,7 @@ exports[`components/signup/Signup should match snapshot for all signup options e error="" info="Must be 5-64 characters long." inputSize="large" + onBlur={[Function]} onChange={[Function]} value="" /> diff --git a/webapp/channels/src/components/signup/signup.tsx b/webapp/channels/src/components/signup/signup.tsx index ca6d6e29fc..dde147597f 100644 --- a/webapp/channels/src/components/signup/signup.tsx +++ b/webapp/channels/src/components/signup/signup.tsx @@ -1,7 +1,8 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React, {useState, useEffect, useRef, useCallback} from 'react'; +import React, {useState, useEffect, useRef, useCallback, FocusEvent} from 'react'; + import {useIntl} from 'react-intl'; import {useLocation, useHistory} from 'react-router-dom'; import {useSelector, useDispatch} from 'react-redux'; @@ -455,16 +456,25 @@ const Signup = ({onCustomizeHeader}: SignupProps) => { } }; + function sendSignUpTelemetryEvents(telemetryId: string, props?: any) { + trackEvent('signup', telemetryId, props); + } + + type TelemetryErrorList = {errors: Array<{field: string; rule: string}>; success: boolean}; + const isUserValid = () => { let isValid = true; const providedEmail = emailInput.current?.value.trim(); + const telemetryEvents: TelemetryErrorList = {errors: [], success: true}; if (!providedEmail) { setEmailError(formatMessage({id: 'signup_user_completed.required', defaultMessage: 'This field is required'})); + telemetryEvents.errors.push({field: 'email', rule: 'not_provided'}); isValid = false; } else if (!isEmail(providedEmail)) { setEmailError(formatMessage({id: 'signup_user_completed.validEmail', defaultMessage: 'Please enter a valid email address'})); + telemetryEvents.errors.push({field: 'email', rule: 'invalid_email'}); isValid = false; } @@ -474,10 +484,11 @@ const Signup = ({onCustomizeHeader}: SignupProps) => { const usernameError = isValidUsername(providedUsername); if (usernameError) { - setNameError(usernameError.id === ValidationErrors.RESERVED_NAME ? ( - formatMessage({id: 'signup_user_completed.reserved', defaultMessage: 'This username is reserved, please choose a new one.'}) - ) : ( - formatMessage( + let nameError = ''; + if (usernameError.id === ValidationErrors.RESERVED_NAME) { + nameError = formatMessage({id: 'signup_user_completed.reserved', defaultMessage: 'This username is reserved, please choose a new one.'}); + } else { + nameError = formatMessage( { id: 'signup_user_completed.usernameLength', defaultMessage: 'Usernames have to begin with a lowercase letter and be {min}-{max} characters long. You can use lowercase letters, numbers, periods, dashes, and underscores.', @@ -486,23 +497,33 @@ const Signup = ({onCustomizeHeader}: SignupProps) => { min: Constants.MIN_USERNAME_LENGTH, max: Constants.MAX_USERNAME_LENGTH, }, - ) - )); + ); + } + telemetryEvents.errors.push({field: 'username', rule: usernameError.id.toLowerCase()}); + setNameError(nameError); isValid = false; } } else { setNameError(formatMessage({id: 'signup_user_completed.required', defaultMessage: 'This field is required'})); + telemetryEvents.errors.push({field: 'username', rule: 'not_provided'}); isValid = false; } const providedPassword = passwordInput.current?.value ?? ''; - const {error} = isValidPassword(providedPassword, getPasswordConfig(config), intl); + const {error, telemetryErrorIds} = isValidPassword(providedPassword, getPasswordConfig(config), intl); if (error) { setPasswordError(error as string); + telemetryEvents.errors = [...telemetryEvents.errors, ...telemetryErrorIds]; isValid = false; } + if (telemetryEvents.errors.length) { + telemetryEvents.success = false; + } + + sendSignUpTelemetryEvents('validate_user', telemetryEvents); + return isValid; }; @@ -512,7 +533,7 @@ const Signup = ({onCustomizeHeader}: SignupProps) => { const handleSubmit = async (e: React.MouseEvent | React.KeyboardEvent) => { e.preventDefault(); - trackEvent('signup_email', 'click_create_account', getRoleFromTrackFlow()); + sendSignUpTelemetryEvents('click_create_account', getRoleFromTrackFlow()); setIsWaiting(true); if (isUserValid()) { @@ -550,6 +571,14 @@ const Signup = ({onCustomizeHeader}: SignupProps) => { const handleReturnButtonOnClick = () => history.replace('/'); + const handleOnBlur = (e: FocusEvent, inputId: string) => { + const text = e.target.value; + if (!text) { + return; + } + sendSignUpTelemetryEvents(`typed_input_${inputId}`); + }; + const getContent = () => { if (!enableSignUpWithEmail && !enableExternalSignup) { return ( @@ -671,6 +700,7 @@ const Signup = ({onCustomizeHeader}: SignupProps) => { disabled={isWaiting || Boolean(parsedEmail)} autoFocus={true} customMessage={emailCustomLabelForInput} + onBlur={(e) => handleOnBlur(e, 'email')} /> { value: formatMessage({id: 'signup_user_completed.userHelp', defaultMessage: 'You can use lowercase letters, numbers, periods, dashes, and underscores.'}), } } + onBlur={(e) => handleOnBlur(e, 'username')} /> { createMode={true} info={passwordInfo as string} error={passwordError} + onBlur={(e) => handleOnBlur(e, 'password')} /> ) { export function isValidPassword(password: string, passwordConfig: ReturnType, intl?: IntlShape) { let errorId = t('user.settings.security.passwordError'); + const telemetryErrorIds = []; let valid = true; const minimumLength = passwordConfig.minimumLength || Constants.MIN_PASSWORD_LENGTH; if (password.length < minimumLength || password.length > Constants.MAX_PASSWORD_LENGTH) { valid = false; + telemetryErrorIds.push({field: 'password', rule: 'error_length'}); } if (passwordConfig.requireLowercase) { @@ -1379,6 +1381,7 @@ export function isValidPassword(password: string, passwordConfig: ReturnType Date: Wed, 29 Mar 2023 13:39:55 +0200 Subject: [PATCH 43/46] MM-47849 - show worktemplate tourtip only once (#22703) --- .../boards_tour_tip.tsx | 7 ++++-- .../playbooks_tour_tip.tsx | 5 +++- .../useShowTourTip.tsx | 9 ++++++-- .../src/components/work_templates/index.tsx | 23 ++++--------------- .../src/components/work_templates/utils.ts | 3 ++- .../src/actions/work_templates.ts | 2 +- webapp/platform/types/src/work_templates.ts | 2 +- 7 files changed, 25 insertions(+), 26 deletions(-) diff --git a/webapp/channels/src/components/tours/worktemplate_explore_tour/boards_tour_tip.tsx b/webapp/channels/src/components/tours/worktemplate_explore_tour/boards_tour_tip.tsx index 46c020a153..dd55ac313d 100644 --- a/webapp/channels/src/components/tours/worktemplate_explore_tour/boards_tour_tip.tsx +++ b/webapp/channels/src/components/tours/worktemplate_explore_tour/boards_tour_tip.tsx @@ -4,6 +4,8 @@ import React from 'react'; import {FormattedMessage, useIntl} from 'react-intl'; +import {useMeasurePunchouts} from '@mattermost/components'; + import OnboardingWorkTemplateTourTip from './worktemplate_explore_tour_tip'; import {useShowTourTip} from './useShowTourTip'; @@ -11,6 +13,7 @@ export const BoardsTourTip = (): JSX.Element | null => { const {formatMessage} = useIntl(); const {playbooksCount, boardsCount, showBoardsTour} = useShowTourTip(); + const overlayPunchOut = useMeasurePunchouts(['sidebar-right'], []); if (!showBoardsTour) { return null; @@ -50,11 +53,11 @@ export const BoardsTourTip = (): JSX.Element | null => { return ( diff --git a/webapp/channels/src/components/tours/worktemplate_explore_tour/playbooks_tour_tip.tsx b/webapp/channels/src/components/tours/worktemplate_explore_tour/playbooks_tour_tip.tsx index fe0ec6427c..d8dbe14116 100644 --- a/webapp/channels/src/components/tours/worktemplate_explore_tour/playbooks_tour_tip.tsx +++ b/webapp/channels/src/components/tours/worktemplate_explore_tour/playbooks_tour_tip.tsx @@ -4,12 +4,15 @@ import React from 'react'; import {FormattedMessage, useIntl} from 'react-intl'; +import {useMeasurePunchouts} from '@mattermost/components'; + import {useShowTourTip} from './useShowTourTip'; import OnboardingWorkTemplateTourTip from './worktemplate_explore_tour_tip'; export const PlaybooksTourTip = (): JSX.Element | null => { const {formatMessage} = useIntl(); const {playbooksCount, boardsCount, showPlaybooksTour} = useShowTourTip(); + const overlayPunchOut = useMeasurePunchouts(['sidebar-right'], []); if (!showPlaybooksTour) { return null; @@ -53,7 +56,7 @@ export const PlaybooksTourTip = (): JSX.Element | null => { title={title} screen={screen} singleTip={boardsCount === 0} - overlayPunchOut={null} + overlayPunchOut={overlayPunchOut} placement='left-start' showOptOut={false} /> diff --git a/webapp/channels/src/components/tours/worktemplate_explore_tour/useShowTourTip.tsx b/webapp/channels/src/components/tours/worktemplate_explore_tour/useShowTourTip.tsx index 0a12f87937..3ed8377e32 100644 --- a/webapp/channels/src/components/tours/worktemplate_explore_tour/useShowTourTip.tsx +++ b/webapp/channels/src/components/tours/worktemplate_explore_tour/useShowTourTip.tsx @@ -3,7 +3,7 @@ import {useSelector} from 'react-redux'; -import {getCurrentUserId} from 'mattermost-redux/selectors/entities/common'; +import {getCurrentChannelId, getCurrentUserId} from 'mattermost-redux/selectors/entities/common'; import {getConfig, getWorkTemplatesLinkedProducts} from 'mattermost-redux/selectors/entities/general'; import {getInt} from 'mattermost-redux/selectors/entities/preferences'; @@ -17,18 +17,22 @@ export const useShowTourTip = () => { const activeRhsComponent = useSelector(getActiveRhsComponent); const pluginId = activeRhsComponent?.pluginId || ''; + const currentChannelId = useSelector(getCurrentChannelId); const currentUserId = useSelector(getCurrentUserId); + const enableTutorial = useSelector(getConfig).EnableTutorial === 'true'; const tutorialStep = useSelector((state: GlobalState) => getInt(state, TutorialTourName.WORK_TEMPLATE_TUTORIAL, currentUserId, 0)); const workTemplateTourTipShown = tutorialStep === WorkTemplateTourSteps.FINISHED; - const showProductTour = !workTemplateTourTipShown && enableTutorial; const channelLinkedItems = useSelector(getWorkTemplatesLinkedProducts); const boardsCount = channelLinkedItems?.boards || 0; const playbooksCount = channelLinkedItems?.playbooks || 0; + const channelId = channelLinkedItems?.channelId || null; + + const showProductTour = channelId && channelId === currentChannelId && !workTemplateTourTipShown && enableTutorial; const showBoardsTour = showProductTour && pluginId === suitePluginIds.boards && boardsCount > 0; const showPlaybooksTour = showProductTour && pluginId === suitePluginIds.playbooks && playbooksCount > 0; @@ -38,5 +42,6 @@ export const useShowTourTip = () => { showPlaybooksTour, boardsCount, playbooksCount, + showProductTour, }; }; diff --git a/webapp/channels/src/components/work_templates/index.tsx b/webapp/channels/src/components/work_templates/index.tsx index 0f157299c6..dc8e1a4a97 100644 --- a/webapp/channels/src/components/work_templates/index.tsx +++ b/webapp/channels/src/components/work_templates/index.tsx @@ -8,7 +8,7 @@ import {useDispatch, useSelector} from 'react-redux'; import styled from 'styled-components'; import LocalizedIcon from 'components/localized_icon'; -import {TTNameMapToATStatusKey, TutorialTourName, WorkTemplateTourSteps} from 'components/tours/constant'; +import {TTNameMapToATStatusKey, TutorialTourName} from 'components/tours/constant'; import {closeModal as closeModalAction} from 'actions/views/modals'; import {trackEvent} from 'actions/telemetry_actions'; @@ -195,18 +195,15 @@ const WorkTemplateModal = () => { * Creates the necessary data in the global store as long storing in DB preferences the tourtip information * @param template current used worktempplate */ - const tourTipActions = async (template: WorkTemplate) => { - const linkedProductsCount = getContentCount(template, playbookTemplates); + const tourTipActions = async (template: WorkTemplate, firstChannelId: string) => { + const linkedProductsCount = getContentCount(template, playbookTemplates, firstChannelId); // stepValue and pluginId are used for showing the tourtip for the used template - let stepValue = 0; let pluginId; if (linkedProductsCount.playbooks) { pluginId = rhsPluggableIds.get(suitePluginIds.playbooks); - stepValue = WorkTemplateTourSteps.PLAYBOOKS_TOUR_TIP; } else { pluginId = rhsPluggableIds.get(suitePluginIds.boards); - stepValue = WorkTemplateTourSteps.BOARDS_TOUR_TIP; } if (!pluginId) { @@ -219,17 +216,8 @@ const WorkTemplateModal = () => { // store the required preferences for the tourtip const tourCategory = TutorialTourName.WORK_TEMPLATE_TUTORIAL; + const preferences = [ - - // here reset the step value to be able to show the tour again (if we dedide to show the tour only once, this must be removed) - { - user_id: currentUserId, - category: tourCategory, - name: currentUserId, - value: stepValue.toString(), - }, - - // this one is for defining the auto tour start for the tour tip { user_id: currentUserId, category: tourCategory, @@ -237,7 +225,6 @@ const WorkTemplateModal = () => { value: String(AutoTourStatus.ENABLED), }, ]; - await dispatch(savePreferences(currentUserId, preferences)); dispatch(showRHSPlugin(pluginId)); @@ -285,7 +272,7 @@ const WorkTemplateModal = () => { dispatch(loadIfNecessaryAndSwitchToChannelById(firstChannelId)); } - await tourTipActions(template); + await tourTipActions(template, firstChannelId); setIsCreating(false); closeModal(); diff --git a/webapp/channels/src/components/work_templates/utils.ts b/webapp/channels/src/components/work_templates/utils.ts index 97b9c9fc4d..c96df206ec 100644 --- a/webapp/channels/src/components/work_templates/utils.ts +++ b/webapp/channels/src/components/work_templates/utils.ts @@ -31,10 +31,11 @@ export function getTemplateDefaultIllustration(template: WorkTemplate): string { return ''; } -export const getContentCount = (template: WorkTemplate, playbookTemplates: PlaybookTemplateType[]) => { +export const getContentCount = (template: WorkTemplate, playbookTemplates: PlaybookTemplateType[], channelId: string) => { const res = { playbooks: 0, boards: 0, + channelId, }; for (const item of template.content) { if (item.playbook) { diff --git a/webapp/channels/src/packages/mattermost-redux/src/actions/work_templates.ts b/webapp/channels/src/packages/mattermost-redux/src/actions/work_templates.ts index c9eda131bd..b9bf3c50be 100644 --- a/webapp/channels/src/packages/mattermost-redux/src/actions/work_templates.ts +++ b/webapp/channels/src/packages/mattermost-redux/src/actions/work_templates.ts @@ -47,7 +47,7 @@ export function clearWorkTemplates(): ActionFunc { } // stores the linked product information in the state so it can be used to show the tourtip -export function onExecuteSuccess(data: Record): ActionFunc { +export function onExecuteSuccess(data: Record): ActionFunc { return async (dispatch) => { dispatch({type: WorkTemplatesType.EXECUTE_SUCCESS, data}); return []; diff --git a/webapp/platform/types/src/work_templates.ts b/webapp/platform/types/src/work_templates.ts index 46e3d29f99..d9d776e566 100644 --- a/webapp/platform/types/src/work_templates.ts +++ b/webapp/platform/types/src/work_templates.ts @@ -7,7 +7,7 @@ export type WorkTemplatesState = { categories: Category[]; templatesInCategory: Record; playbookTemplates: PlaybookTemplateType[]; - linkedProducts: Record; + linkedProducts: Record; } export interface PlaybookTemplateType { From 5da458a16fa3a7fd930b7e9993c32a87983d1fc0 Mon Sep 17 00:00:00 2001 From: Harshil Sharma <18575143+harshilsharma63@users.noreply.github.com> Date: Wed, 29 Mar 2023 17:11:55 +0530 Subject: [PATCH 44/46] Allowed searcginbg users by substring in admin console (#22505) --- .../channels/store/searchtest/user_layer.go | 75 +++++++++++++++++++ server/channels/store/sqlstore/user_store.go | 2 +- .../src/selectors/entities/users.ts | 4 +- 3 files changed, 78 insertions(+), 3 deletions(-) diff --git a/server/channels/store/searchtest/user_layer.go b/server/channels/store/searchtest/user_layer.go index 66527fadde..bb2684b011 100644 --- a/server/channels/store/searchtest/user_layer.go +++ b/server/channels/store/searchtest/user_layer.go @@ -152,6 +152,11 @@ var searchUserStoreTests = []searchTest{ Fn: testSearchUsersInTeamUsernameWithUnderscore, Tags: []string{EngineAll}, }, + { + Name: "Should support search all users containing a substring in any name", + Fn: testSearchUserBySubstringInAnyName, + Tags: []string{EngineAll}, + }, } func TestSearchUserStore(t *testing.T, s store.Store, testEngine *SearchTestEngine) { @@ -865,6 +870,76 @@ func testSearchUsersByFullName(t *testing.T, th *SearchTestHelper) { }) } +func testSearchUserBySubstringInAnyName(t *testing.T, th *SearchTestHelper) { + t.Run("Should search users by substring in first name", func(t *testing.T) { + userAlternate, err := th.createUser("user-alternate", "user-alternate", "alternate helloooo first name", "alternate") + require.NoError(t, err) + defer th.deleteUser(userAlternate) + + // searching user without specifying team + options := createDefaultOptions(true, false, false) + users, err := th.Store.User().Search("", "hello", options) + require.NoError(t, err) + th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users) + + // adding user to team to search by team + err = th.addUserToTeams(userAlternate, []string{th.Team.Id}) + require.NoError(t, err) + + err = th.addUserToChannels(userAlternate, []string{th.ChannelBasic.Id}) + require.NoError(t, err) + + options = createDefaultOptions(true, false, false) + users, err = th.Store.User().Search(th.Team.Id, "hello", options) + require.NoError(t, err) + th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users) + }) + t.Run("Should search users by substring in last name name", func(t *testing.T) { + userAlternate, err := th.createUser("user-alternate", "user-alternate", "alternate", "alternate helloooo last name") + require.NoError(t, err) + defer th.deleteUser(userAlternate) + + options := createDefaultOptions(true, false, false) + users, err := th.Store.User().Search("", "hello", options) + require.NoError(t, err) + th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users) + + // adding user to team to search by team + err = th.addUserToTeams(userAlternate, []string{th.Team.Id}) + require.NoError(t, err) + + err = th.addUserToChannels(userAlternate, []string{th.ChannelBasic.Id}) + require.NoError(t, err) + + options = createDefaultOptions(true, false, false) + users, err = th.Store.User().Search(th.Team.Id, "hello", options) + require.NoError(t, err) + th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users) + }) + t.Run("Should search users by substring in nickname name", func(t *testing.T) { + userAlternate, err := th.createUser("user-alternate", "alternate helloooo nickname", "alternate hello first name", "alternate") + require.NoError(t, err) + defer th.deleteUser(userAlternate) + + options := createDefaultOptions(true, false, false) + users, err := th.Store.User().Search("", "hello", options) + require.NoError(t, err) + th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users) + + // adding user to team to search by team + err = th.addUserToTeams(userAlternate, []string{th.Team.Id}) + require.NoError(t, err) + + err = th.addUserToChannels(userAlternate, []string{th.ChannelBasic.Id}) + require.NoError(t, err) + + options = createDefaultOptions(true, false, false) + users, err = th.Store.User().Search(th.Team.Id, "hello", options) + require.NoError(t, err) + th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users) + }) +} + func createDefaultOptions(allowFullName, allowEmails, allowInactive bool) *model.UserSearchOptions { return &model.UserSearchOptions{ AllowFullNames: allowFullName, diff --git a/server/channels/store/sqlstore/user_store.go b/server/channels/store/sqlstore/user_store.go index c298148af8..293d78c9a4 100644 --- a/server/channels/store/sqlstore/user_store.go +++ b/server/channels/store/sqlstore/user_store.go @@ -1540,7 +1540,7 @@ func generateSearchQuery(query sq.SelectBuilder, terms []string, fields []string } else { searchFields = append(searchFields, fmt.Sprintf("%s LIKE ? escape '*' ", field)) } - termArgs = append(termArgs, fmt.Sprintf("%s%%", strings.TrimLeft(term, "@"))) + termArgs = append(termArgs, fmt.Sprintf("%%%s%%", strings.TrimLeft(term, "@"))) } query = query.Where(fmt.Sprintf("(%s)", strings.Join(searchFields, " OR ")), termArgs...) } diff --git a/webapp/channels/src/packages/mattermost-redux/src/selectors/entities/users.ts b/webapp/channels/src/packages/mattermost-redux/src/selectors/entities/users.ts index 1a79d4526d..131a60a281 100644 --- a/webapp/channels/src/packages/mattermost-redux/src/selectors/entities/users.ts +++ b/webapp/channels/src/packages/mattermost-redux/src/selectors/entities/users.ts @@ -442,7 +442,7 @@ export function makeSearchProfilesStartingWithTerm(): (state: GlobalState, term: (state: GlobalState, term: string, skipCurrent?: boolean) => skipCurrent || false, (stateGlobalState, term: string, skipCurrent?: boolean, filters?: Filters) => filters, (users, currentUserId, term, skipCurrent, filters) => { - const profiles = filterProfilesStartingWithTerm(Object.values(users), term); + const profiles = filterProfilesMatchingWithTerm(Object.values(users), term); return filterFromProfiles(currentUserId, profiles, skipCurrent, filters); }, ); @@ -509,7 +509,7 @@ export function searchProfilesInCurrentTeam(state: GlobalState, term: string, sk } export function searchProfilesInTeam(state: GlobalState, teamId: Team['id'], term: string, skipCurrent = false, filters?: Filters): UserProfile[] { - const profiles = filterProfilesStartingWithTerm(getProfilesInTeam(state, teamId, filters), term); + const profiles = filterProfilesMatchingWithTerm(getProfilesInTeam(state, teamId, filters), term); if (skipCurrent) { removeCurrentUserFromList(profiles, getCurrentUserId(state)); } From 5267dfdcc6cb9bce193596c1349a69bd4e0596c6 Mon Sep 17 00:00:00 2001 From: Ibrahim Serdar Acikgoz Date: Wed, 29 Mar 2023 15:56:12 +0300 Subject: [PATCH 45/46] Cancel in progress workflows but exclude master (#22684) --- .github/workflows/channels-ci.yml | 2 +- .github/workflows/ci.yml | 2 +- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/e2e-tests-ci.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/channels-ci.yml b/.github/workflows/channels-ci.yml index b861650714..39e76631f0 100644 --- a/.github/workflows/channels-ci.yml +++ b/.github/workflows/channels-ci.yml @@ -7,7 +7,7 @@ on: - mono-repo* concurrency: group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true + cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} defaults: run: shell: bash diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 70fe38e71b..6dedcdeb75 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ env: go-version: "1.19.5" concurrency: group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true + cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} jobs: check-mocks: name: Check mocks diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index a023ecd86f..597302f900 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -2,7 +2,7 @@ name: "CodeQL" concurrency: group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true + cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} on: pull_request: diff --git a/.github/workflows/e2e-tests-ci.yml b/.github/workflows/e2e-tests-ci.yml index 075fea0262..89c7cbfeed 100644 --- a/.github/workflows/e2e-tests-ci.yml +++ b/.github/workflows/e2e-tests-ci.yml @@ -7,7 +7,7 @@ on: - mono-repo* concurrency: group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true + cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} defaults: run: shell: bash From c78d6d47acda687ad059440d73f47972a1bf0960 Mon Sep 17 00:00:00 2001 From: Nathaniel Allred Date: Wed, 29 Mar 2023 07:57:52 -0500 Subject: [PATCH 46/46] MM-50952 RFQA can save notifications --- .../src/components/admin_console/admin_definition.jsx | 6 +----- .../components/admin_console/schema_admin_settings.jsx | 9 +++++++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/webapp/channels/src/components/admin_console/admin_definition.jsx b/webapp/channels/src/components/admin_console/admin_definition.jsx index 5eab5ed08f..387b13825b 100644 --- a/webapp/channels/src/components/admin_console/admin_definition.jsx +++ b/webapp/channels/src/components/admin_console/admin_definition.jsx @@ -2497,11 +2497,7 @@ const AdminDefinition = { it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.SITE.NOTIFICATIONS)), it.stateIsFalse('EmailSettings.SendEmailNotifications'), ), - - // MM-50952 - // If the setting is hidden, then it is not being set in state so there is - // nothing to validate, and validation would fail anyways and prevent saving - validate: it.configIsFalse('ExperimentalSettings', 'RestrictSystemAdmin') && validators.isRequired(t('admin.environment.notifications.feedbackEmail.required'), '"Notification From Address" is required'), + validate: validators.isRequired(t('admin.environment.notifications.feedbackEmail.required'), '"Notification From Address" is required'), }, { type: Constants.SettingsTypes.TYPE_TEXT, diff --git a/webapp/channels/src/components/admin_console/schema_admin_settings.jsx b/webapp/channels/src/components/admin_console/schema_admin_settings.jsx index 7faa9825fc..665bc85d25 100644 --- a/webapp/channels/src/components/admin_console/schema_admin_settings.jsx +++ b/webapp/channels/src/components/admin_console/schema_admin_settings.jsx @@ -1126,6 +1126,15 @@ export default class SchemaAdminSettings extends React.PureComponent { } if (setting.validate) { + if (setting.isHidden?.(this.props.config)) { + // MM-50952 + // If the setting is hidden, then it is not being set in state so there is + // nothing to validate, and validation would fail anyways and prevent saving + // In practice, this only happens in custom cloud setup environments like RFQA + // where it sets things in the config file directly instead of in the environment + // (like cloud Mattermost does) + continue; + } const result = setting.validate(this.state[setting.key]); if (!result.isValid()) { return false;