Move /e2e -> /e2e-tests
Этот коммит содержится в:
@@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {expect, Locator} from '@playwright/test';
|
||||
|
||||
export default class BoardsCreateModal {
|
||||
readonly container: Locator;
|
||||
|
||||
readonly productSwitchMenu;
|
||||
|
||||
constructor(container: Locator) {
|
||||
this.container = container;
|
||||
|
||||
this.productSwitchMenu = container.getByRole('button', {name: 'Product switch menu'});
|
||||
}
|
||||
|
||||
async switchProduct(name: string) {
|
||||
await this.productSwitchMenu.click();
|
||||
await this.container.getByRole('link', {name: ` ${name}`}).click();
|
||||
}
|
||||
|
||||
async toBeVisible(name: string) {
|
||||
await expect(this.container.getByRole('heading', {name})).toBeVisible();
|
||||
}
|
||||
}
|
||||
|
||||
export {BoardsCreateModal};
|
||||
28
e2e-tests/playwright/support/ui/components/boards/sidebar.ts
Обычный файл
28
e2e-tests/playwright/support/ui/components/boards/sidebar.ts
Обычный файл
@@ -0,0 +1,28 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {Locator} from '@playwright/test';
|
||||
|
||||
export default class BoardsSidebar {
|
||||
readonly container: Locator;
|
||||
|
||||
readonly plusButton;
|
||||
readonly createNewBoardMenuItem;
|
||||
readonly createNewCategoryMenuItem;
|
||||
readonly titles;
|
||||
|
||||
constructor(container: Locator) {
|
||||
this.container = container;
|
||||
|
||||
this.plusButton = container.locator('.add-board-icon');
|
||||
this.createNewBoardMenuItem = container.getByRole('button', {name: 'Create new board'});
|
||||
this.createNewCategoryMenuItem = container.getByRole('button', {name: 'Create New Category'});
|
||||
this.titles = container.locator('.SidebarBoardItem > .octo-sidebar-title');
|
||||
}
|
||||
|
||||
async waitForTitle(name: string) {
|
||||
await this.container.getByRole('button', {name: ` ${name}`}).waitFor({state: 'visible'});
|
||||
}
|
||||
}
|
||||
|
||||
export {BoardsSidebar};
|
||||
22
e2e-tests/playwright/support/ui/components/channels/app_bar.ts
Обычный файл
22
e2e-tests/playwright/support/ui/components/channels/app_bar.ts
Обычный файл
@@ -0,0 +1,22 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {expect, Locator} from '@playwright/test';
|
||||
|
||||
export default class ChannelsAppBar {
|
||||
readonly container: Locator;
|
||||
|
||||
readonly playbooksIcon;
|
||||
|
||||
constructor(container: Locator) {
|
||||
this.container = container;
|
||||
|
||||
this.playbooksIcon = container.locator('#app-bar-icon-playbooks').getByRole('img');
|
||||
}
|
||||
|
||||
async toBeVisible() {
|
||||
await expect(this.container).toBeVisible();
|
||||
}
|
||||
}
|
||||
|
||||
export {ChannelsAppBar};
|
||||
18
e2e-tests/playwright/support/ui/components/channels/header.ts
Обычный файл
18
e2e-tests/playwright/support/ui/components/channels/header.ts
Обычный файл
@@ -0,0 +1,18 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {expect, Locator} from '@playwright/test';
|
||||
|
||||
export default class ChannelsHeader {
|
||||
readonly container: Locator;
|
||||
|
||||
constructor(container: Locator) {
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
async toBeVisible() {
|
||||
await expect(this.container).toBeVisible();
|
||||
}
|
||||
}
|
||||
|
||||
export {ChannelsHeader};
|
||||
42
e2e-tests/playwright/support/ui/components/channels/post.ts
Обычный файл
42
e2e-tests/playwright/support/ui/components/channels/post.ts
Обычный файл
@@ -0,0 +1,42 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {expect, Locator} from '@playwright/test';
|
||||
|
||||
export default class ChannelsPost {
|
||||
readonly container: Locator;
|
||||
|
||||
readonly body;
|
||||
readonly profileIcon;
|
||||
readonly replyButton;
|
||||
|
||||
constructor(container: Locator) {
|
||||
this.container = container;
|
||||
|
||||
this.body = container.locator('.post__body');
|
||||
this.profileIcon = container.locator('.profile-icon');
|
||||
this.replyButton = container.getByRole('button', {name: 'reply'});
|
||||
}
|
||||
|
||||
async toBeVisible() {
|
||||
await expect(this.container).toBeVisible();
|
||||
}
|
||||
|
||||
async getId() {
|
||||
const id = await this.container.getAttribute('id');
|
||||
expect(id, 'No post ID found.').toBeTruthy();
|
||||
return (id || '').substring('post_'.length);
|
||||
}
|
||||
|
||||
async getProfileImage(username: string) {
|
||||
return await this.profileIcon.getByAltText(`${username} profile image`);
|
||||
}
|
||||
|
||||
async openRHS() {
|
||||
await this.container.hover();
|
||||
await this.replyButton.waitFor();
|
||||
await this.replyButton.click();
|
||||
}
|
||||
}
|
||||
|
||||
export {ChannelsPost};
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {expect, Locator} from '@playwright/test';
|
||||
|
||||
export default class ChannelsPostCreate {
|
||||
readonly container: Locator;
|
||||
|
||||
readonly input;
|
||||
readonly attachmentButton;
|
||||
readonly emojiButton;
|
||||
|
||||
constructor(container: Locator) {
|
||||
this.container = container;
|
||||
|
||||
this.input = container.getByTestId('post_textbox');
|
||||
this.attachmentButton = container.getByLabel('attachment');
|
||||
this.emojiButton = container.getByLabel('select an emoji');
|
||||
}
|
||||
|
||||
async postMessage(message: string) {
|
||||
await this.input.fill(message);
|
||||
}
|
||||
|
||||
async toBeVisible() {
|
||||
await expect(this.container).toBeVisible();
|
||||
await expect(this.input).toBeVisible();
|
||||
}
|
||||
}
|
||||
|
||||
export {ChannelsPostCreate};
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {expect, Locator} from '@playwright/test';
|
||||
|
||||
export default class ChannelsSidebarRight {
|
||||
readonly container: Locator;
|
||||
|
||||
constructor(container: Locator) {
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
async toBeVisible() {
|
||||
await expect(this.container).toBeVisible();
|
||||
}
|
||||
}
|
||||
|
||||
export {ChannelsSidebarRight};
|
||||
27
e2e-tests/playwright/support/ui/components/global_header.ts
Обычный файл
27
e2e-tests/playwright/support/ui/components/global_header.ts
Обычный файл
@@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {expect, Locator} from '@playwright/test';
|
||||
|
||||
export default class GlobalHeader {
|
||||
readonly container: Locator;
|
||||
|
||||
readonly productSwitchMenu;
|
||||
|
||||
constructor(container: Locator) {
|
||||
this.container = container;
|
||||
|
||||
this.productSwitchMenu = container.getByRole('button', {name: 'Product switch menu'});
|
||||
}
|
||||
|
||||
async switchProduct(name: string) {
|
||||
await this.productSwitchMenu.click();
|
||||
await this.container.getByRole('link', {name: ` ${name}`}).click();
|
||||
}
|
||||
|
||||
async toBeVisible(name: string) {
|
||||
await expect(this.container.getByRole('heading', {name})).toBeVisible();
|
||||
}
|
||||
}
|
||||
|
||||
export {GlobalHeader};
|
||||
31
e2e-tests/playwright/support/ui/components/index.ts
Обычный файл
31
e2e-tests/playwright/support/ui/components/index.ts
Обычный файл
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {BoardsSidebar} from './boards/sidebar';
|
||||
import {ChannelsHeader} from './channels/header';
|
||||
import {ChannelsAppBar} from './channels/app_bar';
|
||||
import {ChannelsPostCreate} from './channels/post_create';
|
||||
import {ChannelsPost} from './channels/post';
|
||||
import {ChannelsSidebarRight} from './channels/sidebar_right';
|
||||
import {GlobalHeader} from './global_header';
|
||||
|
||||
const components = {
|
||||
BoardsSidebar,
|
||||
ChannelsAppBar,
|
||||
ChannelsHeader,
|
||||
ChannelsPostCreate,
|
||||
ChannelsPost,
|
||||
ChannelsSidebarRight,
|
||||
GlobalHeader,
|
||||
};
|
||||
|
||||
export {
|
||||
components,
|
||||
BoardsSidebar,
|
||||
ChannelsAppBar,
|
||||
ChannelsHeader,
|
||||
ChannelsPostCreate,
|
||||
ChannelsPost,
|
||||
ChannelsSidebarRight,
|
||||
GlobalHeader,
|
||||
};
|
||||
47
e2e-tests/playwright/support/ui/pages/boards_create.ts
Обычный файл
47
e2e-tests/playwright/support/ui/pages/boards_create.ts
Обычный файл
@@ -0,0 +1,47 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {expect, Page} from '@playwright/test';
|
||||
|
||||
import {components} from '@e2e-support/ui/components';
|
||||
|
||||
export default class BoardsCreatePage {
|
||||
readonly boards = 'Boards';
|
||||
readonly page: Page;
|
||||
|
||||
readonly globalHeader;
|
||||
|
||||
readonly createBoardHeading;
|
||||
readonly createEmptyBoardButton;
|
||||
readonly useTemplateButton;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
this.globalHeader = new components.GlobalHeader(this.page.locator('#global-header'));
|
||||
this.createBoardHeading = page.getByRole('heading', {name: 'Create a board'});
|
||||
this.createEmptyBoardButton = page.getByRole('button', {name: ' Create an empty board'});
|
||||
this.useTemplateButton = page.getByRole('button', {name: 'Use this template'});
|
||||
}
|
||||
|
||||
async goto(teamId = '') {
|
||||
let boardsUrl = '/boards';
|
||||
if (teamId) {
|
||||
boardsUrl += `/team/${teamId}`;
|
||||
}
|
||||
|
||||
await this.page.goto(boardsUrl);
|
||||
}
|
||||
|
||||
async toBeVisible() {
|
||||
await this.globalHeader.toBeVisible(this.boards);
|
||||
await expect(this.createEmptyBoardButton).toBeVisible();
|
||||
await expect(this.useTemplateButton).toBeVisible();
|
||||
await expect(this.createBoardHeading).toBeVisible();
|
||||
}
|
||||
|
||||
async createEmptyBoard() {
|
||||
await this.createEmptyBoardButton.click();
|
||||
}
|
||||
}
|
||||
|
||||
export {BoardsCreatePage};
|
||||
60
e2e-tests/playwright/support/ui/pages/boards_view.ts
Обычный файл
60
e2e-tests/playwright/support/ui/pages/boards_view.ts
Обычный файл
@@ -0,0 +1,60 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {expect, Page} from '@playwright/test';
|
||||
|
||||
import {components} from '@e2e-support/ui/components';
|
||||
|
||||
export default class BoardsViewPage {
|
||||
readonly boards = 'Boards';
|
||||
readonly page: Page;
|
||||
|
||||
readonly sidebar;
|
||||
readonly globalHeader;
|
||||
|
||||
readonly topHead;
|
||||
readonly editableTitle;
|
||||
readonly shareButton;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
this.sidebar = new components.BoardsSidebar(page.locator('.octo-sidebar'));
|
||||
this.globalHeader = new components.GlobalHeader(this.page.locator('#global-header'));
|
||||
this.topHead = page.locator('.top-head');
|
||||
this.editableTitle = this.topHead.getByPlaceholder('Untitled board');
|
||||
this.shareButton = page.getByRole('button', {name: ' Share'});
|
||||
}
|
||||
|
||||
async goto(teamId = '', boardId = '', viewId = '', cardId = '') {
|
||||
let boardsUrl = '/boards';
|
||||
if (teamId) {
|
||||
boardsUrl += `/team/${teamId}`;
|
||||
if (boardId) {
|
||||
boardsUrl += `/${boardId}`;
|
||||
if (viewId) {
|
||||
boardsUrl += `/${viewId}`;
|
||||
if (cardId) {
|
||||
boardsUrl += `/${cardId}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await this.page.goto(boardsUrl);
|
||||
}
|
||||
|
||||
async toBeVisible() {
|
||||
await this.page.waitForLoadState('networkidle');
|
||||
await this.globalHeader.toBeVisible(this.boards);
|
||||
await expect(this.shareButton).toBeVisible();
|
||||
await expect(this.topHead).toBeVisible();
|
||||
}
|
||||
|
||||
async shouldHaveUntitledBoard() {
|
||||
await this.editableTitle.isVisible();
|
||||
expect(await this.editableTitle.getAttribute('value')).toBe('');
|
||||
await expect(this.page.getByTitle('(Untitled Board)')).toBeVisible();
|
||||
}
|
||||
}
|
||||
|
||||
export {BoardsViewPage};
|
||||
106
e2e-tests/playwright/support/ui/pages/channels.ts
Обычный файл
106
e2e-tests/playwright/support/ui/pages/channels.ts
Обычный файл
@@ -0,0 +1,106 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {Page} from '@playwright/test';
|
||||
|
||||
import {waitUntil} from '@e2e-support/test_action';
|
||||
import {components} from '@e2e-support/ui/components';
|
||||
import {duration, isSmallScreen} from '@e2e-support/util';
|
||||
|
||||
export default class ChannelsPage {
|
||||
readonly channels = 'Channels';
|
||||
readonly page: Page;
|
||||
readonly postCreate;
|
||||
readonly globalHeader;
|
||||
readonly header;
|
||||
readonly appBar;
|
||||
readonly sidebarRight;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
this.postCreate = new components.ChannelsPostCreate(page.locator('#post-create'));
|
||||
this.globalHeader = new components.GlobalHeader(page.locator('#global-header'));
|
||||
this.header = new components.ChannelsHeader(page.locator('.channel-header'));
|
||||
this.appBar = new components.ChannelsAppBar(page.locator('.app-bar'));
|
||||
this.sidebarRight = new components.ChannelsSidebarRight(page.locator('#sidebar-right'));
|
||||
}
|
||||
|
||||
async goto(teamName = '', channelName = '') {
|
||||
let channelsUrl = '/';
|
||||
if (teamName) {
|
||||
channelsUrl += `${teamName}`;
|
||||
if (channelName) {
|
||||
channelsUrl += `/${channelName}`;
|
||||
}
|
||||
}
|
||||
|
||||
await this.page.goto(channelsUrl);
|
||||
}
|
||||
|
||||
async toBeVisible() {
|
||||
if (!isSmallScreen(this.page.viewportSize())) {
|
||||
await this.globalHeader.toBeVisible(this.channels);
|
||||
}
|
||||
await this.postCreate.toBeVisible();
|
||||
}
|
||||
|
||||
async postMessage(message: string) {
|
||||
await this.postCreate.input.waitFor();
|
||||
await this.postCreate.postMessage(message);
|
||||
}
|
||||
|
||||
async getFirstPost() {
|
||||
await this.page.getByTestId('postView').first().waitFor();
|
||||
const post = await this.page.getByTestId('postView').first();
|
||||
return new components.ChannelsPost(post);
|
||||
}
|
||||
|
||||
async getLastPost() {
|
||||
await this.page.getByTestId('postView').last().waitFor();
|
||||
const post = await this.page.getByTestId('postView').last();
|
||||
return new components.ChannelsPost(post);
|
||||
}
|
||||
|
||||
async getNthPost(index: number) {
|
||||
await this.page.getByTestId('postView').nth(index).waitFor();
|
||||
const post = await this.page.getByTestId('postView').nth(index);
|
||||
return new components.ChannelsPost(post);
|
||||
}
|
||||
|
||||
async getPostById(id: string) {
|
||||
await this.page.locator(`[id="post_${id}"]`).waitFor();
|
||||
const post = await this.page.locator(`[id="post_${id}"]`);
|
||||
return new components.ChannelsPost(post);
|
||||
}
|
||||
|
||||
async getRHSPostById(id: string) {
|
||||
await this.page.locator(`[id="rhsPost_${id}"]`).waitFor();
|
||||
const post = await this.page.locator(`[id="rhsPost_${id}"]`);
|
||||
return new components.ChannelsPost(post);
|
||||
}
|
||||
|
||||
async waitUntilLastPostContains(text: string, timeout = duration.ten_sec) {
|
||||
await waitUntil(
|
||||
async () => {
|
||||
const post = await this.getLastPost();
|
||||
const content = await post.container.textContent();
|
||||
return content?.includes(text);
|
||||
},
|
||||
{timeout}
|
||||
);
|
||||
}
|
||||
|
||||
async waitUntilPostWithIdContains(id: string, text: string, timeout = duration.ten_sec) {
|
||||
await waitUntil(
|
||||
async () => {
|
||||
const post = await this.getPostById(id);
|
||||
const content = await post.container.textContent();
|
||||
|
||||
return content?.includes(text);
|
||||
},
|
||||
{timeout}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export {ChannelsPage};
|
||||
20
e2e-tests/playwright/support/ui/pages/index.ts
Обычный файл
20
e2e-tests/playwright/support/ui/pages/index.ts
Обычный файл
@@ -0,0 +1,20 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {BoardsCreatePage} from './boards_create';
|
||||
import {BoardsViewPage} from './boards_view';
|
||||
import {ChannelsPage} from './channels';
|
||||
import {LandingLoginPage} from './landing_login';
|
||||
import {LoginPage} from './login';
|
||||
import {SignupPage} from './signup';
|
||||
|
||||
const pages = {
|
||||
BoardsCreatePage,
|
||||
BoardsViewPage,
|
||||
ChannelsPage,
|
||||
LandingLoginPage,
|
||||
LoginPage,
|
||||
SignupPage,
|
||||
};
|
||||
|
||||
export {pages, BoardsCreatePage, BoardsViewPage, ChannelsPage, LandingLoginPage, LoginPage, SignupPage};
|
||||
41
e2e-tests/playwright/support/ui/pages/landing_login.ts
Обычный файл
41
e2e-tests/playwright/support/ui/pages/landing_login.ts
Обычный файл
@@ -0,0 +1,41 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {expect, Page} from '@playwright/test';
|
||||
|
||||
export default class LandingLoginPage {
|
||||
readonly page: Page;
|
||||
|
||||
readonly isMobile?: boolean;
|
||||
|
||||
readonly viewInAppButton;
|
||||
readonly viewInDesktopAppButton;
|
||||
readonly viewInBrowserButton;
|
||||
|
||||
constructor(page: Page, isMobile?: boolean) {
|
||||
this.page = page;
|
||||
this.isMobile = isMobile;
|
||||
|
||||
this.viewInAppButton = page.locator('text=View in App');
|
||||
this.viewInDesktopAppButton = page.locator('text=View in Desktop App');
|
||||
this.viewInBrowserButton = page.locator('text=View in Browser');
|
||||
}
|
||||
|
||||
async toBeVisible() {
|
||||
await this.page.waitForLoadState('networkidle');
|
||||
|
||||
if (this.isMobile) {
|
||||
await expect(this.viewInAppButton).toBeVisible();
|
||||
} else {
|
||||
await expect(this.viewInDesktopAppButton).toBeVisible();
|
||||
}
|
||||
|
||||
await expect(this.viewInBrowserButton).toBeVisible();
|
||||
}
|
||||
|
||||
async goto() {
|
||||
await this.page.goto('/landing#/login');
|
||||
}
|
||||
}
|
||||
|
||||
export {LandingLoginPage};
|
||||
67
e2e-tests/playwright/support/ui/pages/login.ts
Обычный файл
67
e2e-tests/playwright/support/ui/pages/login.ts
Обычный файл
@@ -0,0 +1,67 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {expect, Page} from '@playwright/test';
|
||||
|
||||
import {AdminConfig} from '@mattermost/types/config';
|
||||
import {UserProfile} from '@mattermost/types/users';
|
||||
|
||||
export default class LoginPage {
|
||||
readonly adminConfig: AdminConfig;
|
||||
|
||||
readonly page: Page;
|
||||
|
||||
readonly title;
|
||||
readonly subtitle;
|
||||
readonly bodyCard;
|
||||
readonly loginInput;
|
||||
readonly loginPlaceholder;
|
||||
readonly passwordInput;
|
||||
readonly signInButton;
|
||||
readonly createAccountLink;
|
||||
readonly forgotPasswordLink;
|
||||
readonly userErrorLabel;
|
||||
readonly fieldWithError;
|
||||
readonly formContainer;
|
||||
|
||||
constructor(page: Page, adminConfig: AdminConfig) {
|
||||
this.page = page;
|
||||
this.adminConfig = adminConfig;
|
||||
|
||||
const loginInputPlaceholder = adminConfig.LdapSettings.Enable
|
||||
? 'Email, Username or AD/LDAP Username'
|
||||
: 'Email or Username';
|
||||
|
||||
this.title = page.locator('h1:has-text("Log in to your account")');
|
||||
this.subtitle = page.locator('text=Collaborate with your team in real-time');
|
||||
this.bodyCard = page.locator('.login-body-card');
|
||||
this.loginInput = page.locator('#input_loginId');
|
||||
this.loginPlaceholder = page.locator(`[placeholder="${loginInputPlaceholder}"]`);
|
||||
this.passwordInput = page.locator('#input_password-input');
|
||||
this.signInButton = page.locator('button:has-text("Log in")');
|
||||
this.createAccountLink = page.locator("text=Don't have an account?");
|
||||
this.forgotPasswordLink = page.locator('text=Forgot your password?');
|
||||
this.userErrorLabel = page.locator('text=Please enter your email or username');
|
||||
this.fieldWithError = page.locator('.with-error');
|
||||
this.formContainer = page.locator('.signup-team__container');
|
||||
}
|
||||
|
||||
async toBeVisible() {
|
||||
await this.page.waitForLoadState('networkidle');
|
||||
await expect(this.title).toBeVisible();
|
||||
await expect(this.loginInput).toBeVisible();
|
||||
await expect(this.passwordInput).toBeVisible();
|
||||
}
|
||||
|
||||
async goto() {
|
||||
await this.page.goto('/login');
|
||||
}
|
||||
|
||||
async login(user: UserProfile, useUsername = true) {
|
||||
await this.loginInput.fill(useUsername ? user.username : user.email);
|
||||
await this.passwordInput.fill(user.password);
|
||||
await Promise.all([this.page.waitForNavigation(), this.signInButton.click()]);
|
||||
}
|
||||
}
|
||||
|
||||
export {LoginPage};
|
||||
67
e2e-tests/playwright/support/ui/pages/signup.ts
Обычный файл
67
e2e-tests/playwright/support/ui/pages/signup.ts
Обычный файл
@@ -0,0 +1,67 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {expect, Page} from '@playwright/test';
|
||||
|
||||
import {duration, wait} from '@e2e-support/util';
|
||||
|
||||
export default class SignupPage {
|
||||
readonly page: Page;
|
||||
|
||||
readonly title;
|
||||
readonly subtitle;
|
||||
readonly bodyCard;
|
||||
readonly emailInput;
|
||||
readonly usernameInput;
|
||||
readonly passwordInput;
|
||||
readonly createAccountButton;
|
||||
readonly loginLink;
|
||||
readonly emailError;
|
||||
readonly usernameError;
|
||||
readonly passwordError;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
|
||||
this.title = page.locator('h1:has-text("Let’s get started")');
|
||||
this.subtitle = page.locator('text=Create your Mattermost account to start collaborating with your team');
|
||||
this.bodyCard = page.locator('.signup-body-card');
|
||||
this.emailInput = page.locator('#input_email');
|
||||
this.usernameInput = page.locator('#input_name');
|
||||
this.passwordInput = page.locator('#input_password-input');
|
||||
this.createAccountButton = page.locator('button:has-text("Create Account")');
|
||||
this.loginLink = page.locator('text=Click here to sign in.');
|
||||
this.emailError = page.locator('text=Please enter a valid email address');
|
||||
this.usernameError = page.locator(
|
||||
'text=Usernames have to begin with a lowercase letter and be 3-22 characters long. You can use lowercase letters, numbers, periods, dashes, and underscores.'
|
||||
);
|
||||
this.passwordError = page.locator('text=Must be 5-64 characters long.');
|
||||
}
|
||||
|
||||
async toBeVisible() {
|
||||
await this.page.waitForLoadState('networkidle');
|
||||
await this.page.waitForLoadState('domcontentloaded');
|
||||
await wait(duration.half_sec);
|
||||
await expect(this.title).toBeVisible();
|
||||
await expect(this.emailInput).toBeVisible();
|
||||
await expect(this.usernameInput).toBeVisible();
|
||||
await expect(this.passwordInput).toBeVisible();
|
||||
}
|
||||
|
||||
async goto() {
|
||||
await this.page.goto('/signup_email');
|
||||
}
|
||||
|
||||
async create(user: {email: string; username: string; password: string}, waitForRedirect = true) {
|
||||
await this.emailInput.fill(user.email);
|
||||
await this.usernameInput.fill(user.username);
|
||||
await this.passwordInput.fill(user.password);
|
||||
await this.createAccountButton.click();
|
||||
|
||||
if (waitForRedirect) {
|
||||
await this.page.waitForNavigation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export {SignupPage};
|
||||
Ссылка в новой задаче
Block a user