[Cypress] Rework "cypress-tests" module with using "InversifyJS" library (#13036)

7.20.x
Igor Ohrimenko 2019-04-01 17:28:07 +03:00 committed by GitHub
parent 3704ffccec
commit 8ded9dd01b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 194 additions and 97 deletions

2
.gitignore vendored
View File

@ -92,4 +92,4 @@ requirements.lock
*/coverage
*/.grunt
*/.lock-wscript
*/cypress-tests/dist

View File

@ -17,7 +17,6 @@
* 4. Check Language Server initialization
* 5. Delete workspace using dashboard
*/
import { LoginPage } from "../pageobjects/dashboard/LoginPage";
import { Dashboard } from "../pageobjects/dashboard/Dashboard";
import { Workspaces } from "../pageobjects/dashboard/Workspaces";
import { NewWorkspace } from "../pageobjects/dashboard/NewWorkspace";
@ -25,12 +24,15 @@ import { Ide } from "../pageobjects/ide/Ide";
import { ProjectTree } from "../pageobjects/ide/ProjectTree";
import { Editor } from "../pageobjects/ide/Editor";
import { NameGenerator } from "../utils/NameGenerator";
import { ILoginPage } from "../pageobjects/dashboard/interfaces/ILoginPage";
import { e2eContainer } from "../inversifyJS/inversify.config";
import { TYPES } from "../inversifyJS/types";
const workspaceName: string = NameGenerator.generate("wksp-test-", 5);
const namespace: string = "che";
const sampleName: string = "console-java-simple";
const loginPage: LoginPage = new LoginPage();
const loginPage: ILoginPage = e2eContainer.get<ILoginPage>(TYPES.ILoginPage);
const dashboard: Dashboard = new Dashboard();
const workspaces: Workspaces = new Workspaces();
const newWorkspace: NewWorkspace = new NewWorkspace();
@ -43,7 +45,7 @@ describe("E2E test", () => {
context("Prepare dashboard", () => {
it("Open dashboard", () => {
dashboard.openDashboard();
loginPage.login();
dashboard.waitLoaderPage();
dashboard.waitLoaderPageAbcence()
dashboard.waitDashboard();

View File

@ -0,0 +1,21 @@
import { Container } from "inversify";
import { ILoginPage } from "../pageobjects/dashboard/interfaces/ILoginPage";
import { TYPES } from "./types";
import { LoginPageSingleUser } from "../pageobjects/dashboard/LoginPageSingleUser";
/*********************************************************************
* Copyright (c) 2018 Red Hat, Inc.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/
const e2eContainer = new Container();
e2eContainer.bind<ILoginPage>(TYPES.ILoginPage).to(LoginPageSingleUser)
export {e2eContainer}

View File

@ -0,0 +1,13 @@
/*********************************************************************
* Copyright (c) 2018 Red Hat, Inc.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/
export const TYPES = {
ILoginPage: Symbol.for("ILoginPage")
}

View File

@ -1,72 +0,0 @@
/*********************************************************************
* Copyright (c) 2018 Red Hat, Inc.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/
/// <reference types="Cypress" />
export class LoginPage {
private static readonly LOAD_PAGE_TIMEOUT: number = Cypress.env('load_page_timeout');
private static readonly TEST_USER_NANE: string = Cypress.env('test_user_name');
private static readonly TEST_USER_PASSWORD: string = Cypress.env('test_user_password');
private static readonly USERNAME_FIELD: string = "#username";
private static readonly PASSWORD_FIELD: string = "#password";
private static readonly LOGIN_BUTTON: string = "[name='login']";
private typeToInputField(text: string, fieldLocator: string) {
cy.get(fieldLocator)
.click()
.focus()
.type(text);
}
visitLoginPage() {
cy.visit("/");
}
typeUsername(username: string) {
this.typeToInputField(username, LoginPage.USERNAME_FIELD);
}
typePassword(password: string) {
this.typeToInputField(password, LoginPage.PASSWORD_FIELD);
}
clickOnLoginButton() {
cy.get(LoginPage.LOGIN_BUTTON).click();
}
waitPage() {
[LoginPage.LOGIN_BUTTON, LoginPage.USERNAME_FIELD, LoginPage.PASSWORD_FIELD]
.forEach(elementLocator => {
cy.get(elementLocator, { timeout: LoginPage.LOAD_PAGE_TIMEOUT }).should('be.visible');
})
}
waitPageAbcence() {
[LoginPage.LOGIN_BUTTON, LoginPage.USERNAME_FIELD, LoginPage.PASSWORD_FIELD]
.forEach(elementLocator => {
cy.get(elementLocator, { timeout: LoginPage.LOAD_PAGE_TIMEOUT }).should('not.be.visible');
})
}
login(username: string, password: string) {
this.waitPage();
this.typeUsername(username);
this.typePassword(password);
this.clickOnLoginButton();
this.waitPageAbcence();
}
defaultLogin() {
this.login(LoginPage.TEST_USER_NANE, LoginPage.TEST_USER_PASSWORD);
}
}

View File

@ -0,0 +1,81 @@
import { ILoginPage } from "./interfaces/ILoginPage";
import { Dashboard } from "./Dashboard";
import { injectable, inject } from "inversify";
import "reflect-metadata";
/*********************************************************************
* Copyright (c) 2018 Red Hat, Inc.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/
/// <reference types="Cypress" />
@injectable()
export class LoginPageMultiUser implements ILoginPage {
private static readonly LOAD_PAGE_TIMEOUT: number = Cypress.env('load_page_timeout');
private static readonly TEST_USER_NANE: string = Cypress.env('test_user_name');
private static readonly TEST_USER_PASSWORD: string = Cypress.env('test_user_password');
private readonly dashboard: Dashboard = new Dashboard();
private static readonly USERNAME_FIELD: string = "#username";
private static readonly PASSWORD_FIELD: string = "#password";
private static readonly LOGIN_BUTTON: string = "[name='login']";
private typeToInputField(text: string, fieldLocator: string) {
cy.get(fieldLocator)
.click()
.focus()
.type(text);
}
private visitLoginPage() {
cy.visit("/");
}
private typeUsername(username: string) {
this.typeToInputField(username, LoginPageMultiUser.USERNAME_FIELD);
}
private typePassword(password: string) {
this.typeToInputField(password, LoginPageMultiUser.PASSWORD_FIELD);
}
private clickOnLoginButton() {
cy.get(LoginPageMultiUser.LOGIN_BUTTON)
.click();
}
private waitPage() {
[LoginPageMultiUser.LOGIN_BUTTON, LoginPageMultiUser.USERNAME_FIELD, LoginPageMultiUser.PASSWORD_FIELD]
.forEach(elementLocator => {
cy.get(elementLocator, { timeout: LoginPageMultiUser.LOAD_PAGE_TIMEOUT })
.should('be.visible');
})
}
private waitPageAbcence() {
[LoginPageMultiUser.LOGIN_BUTTON, LoginPageMultiUser.USERNAME_FIELD, LoginPageMultiUser.PASSWORD_FIELD]
.forEach(elementLocator => {
cy.get(elementLocator, { timeout: LoginPageMultiUser.LOAD_PAGE_TIMEOUT })
.should('not.be.visible');
})
}
login() {
this.visitLoginPage();
this.waitPage();
this.typeUsername(LoginPageMultiUser.TEST_USER_NANE);
this.typePassword(LoginPageMultiUser.TEST_USER_PASSWORD);
this.clickOnLoginButton();
this.waitPageAbcence();
}
}

View File

@ -0,0 +1,24 @@
import { injectable } from "inversify";
import "reflect-metadata";
import { ILoginPage } from "./interfaces/ILoginPage";
/*********************************************************************
* Copyright (c) 2018 Red Hat, Inc.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/
/// <reference types="Cypress" />
@injectable()
export class LoginPageSingleUser implements ILoginPage {
login(){
cy.visit("/");
}
}

View File

@ -0,0 +1,13 @@
/*********************************************************************
* Copyright (c) 2018 Red Hat, Inc.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/
export interface ILoginPage{
login():void;
}

View File

@ -10,7 +10,6 @@
/// <reference types="Cypress" />
import { Promise, reject } from "bluebird";
export class Editor {
@ -95,8 +94,8 @@ export class Editor {
return lineCoordinate;
}
public addAttributeToLines(): Promise<number> {
return new Promise<number>((resolve, reject) => {
public addAttributeToLines(): PromiseLike<number> {
return new Cypress.Promise<number>((resolve:any, reject:any) => {
let elementsArray: Array<JQuery<HTMLElement>> = new Array();
cy.get(Editor.EDITOR_LINES)

View File

@ -22,7 +22,7 @@ export class Ide {
private static readonly TOP_MENU_PANEL: string = "#theia-app-shell #theia-top-panel .p-MenuBar-content";
private static readonly LEFT_CONTENT_PANEL: string = "#theia-left-content-panel";
public static readonly FILES_BUTTON: string = ".theia-app-left .p-TabBar-content li[title='Files']";
public static readonly EXPLORER_BUTTON: string = ".theia-app-left .p-TabBar-content li[title='Explorer']";
private static readonly PRELOADER: string = ".theia-preload";
private static readonly IDE_IFRAME: string = "iframe#ide-application-iframe";
@ -57,7 +57,7 @@ export class Ide {
cy.log("**Wait until defined parts of IDE are visible**")
})
.then(() => {
[Ide.TOP_MENU_PANEL, Ide.LEFT_CONTENT_PANEL, Ide.FILES_BUTTON]
[Ide.TOP_MENU_PANEL, Ide.LEFT_CONTENT_PANEL, Ide.EXPLORER_BUTTON]
.forEach(idePartLocator => {
cy.get(Ide.IDE_IFRAME, { timeout: Ide.LOAD_PAGE_TIMEOUT })
.should(iframe => {
@ -74,7 +74,7 @@ export class Ide {
this.testWorkspaceUtil.waitWorkspaceRunning(workspaceNamespace, workspaceName)
})
.then(() => {
[Ide.TOP_MENU_PANEL, Ide.LEFT_CONTENT_PANEL, Ide.FILES_BUTTON]
[Ide.TOP_MENU_PANEL, Ide.LEFT_CONTENT_PANEL, Ide.EXPLORER_BUTTON]
.forEach(idePart => {
cy.get(idePart, { timeout: Ide.LOAD_PAGE_TIMEOUT })
.should('be.visible')
@ -83,7 +83,7 @@ export class Ide {
}
waitIde() {
[Ide.TOP_MENU_PANEL, Ide.LEFT_CONTENT_PANEL, Ide.FILES_BUTTON]
[Ide.TOP_MENU_PANEL, Ide.LEFT_CONTENT_PANEL, Ide.EXPLORER_BUTTON]
.forEach(idePart => {
cy.get(idePart, { timeout: Ide.LOAD_PAGE_TIMEOUT })
.should('be.visible')
@ -99,13 +99,13 @@ export class Ide {
})
}
waitFilesButton() {
cy.get(Ide.FILES_BUTTON)
waitExplorerButton() {
cy.get(Ide.EXPLORER_BUTTON)
.should('be.visible');
}
clickOnFilesButton() {
cy.get(Ide.FILES_BUTTON)
clickOnExplorerButton() {
cy.get(Ide.EXPLORER_BUTTON)
.first()
.click();
}

View File

@ -33,14 +33,14 @@ export class ProjectTree {
}
openProjectTreeContainer() {
cy.get(Ide.FILES_BUTTON)
cy.get(Ide.EXPLORER_BUTTON)
.should('be.visible')
.then(filesButton => {
let isProjectTreeContainerOpened: boolean = filesButton.hasClass("p-mod-current");
//if project tree container is not opened click on "Files" button
if (!isProjectTreeContainerOpened) {
this.ide.clickOnFilesButton();
this.ide.clickOnExplorerButton();
}
}).then(() => {
this.waitProjectTreeContainer();
@ -170,8 +170,8 @@ export class ProjectTree {
})
}
private doWaitProjectImported(projectName: string, rootSubitem: string, attempts: number, currentAttempt: number, pollingEvery: number): Promise<void> {
return new Promise((resolve, reject) => {
private doWaitProjectImported(projectName: string, rootSubitem: string, attempts: number, currentAttempt: number, pollingEvery: number): PromiseLike<void> {
return new Cypress.Promise((resolve:any, reject:any) => {
let rootItem: string = `/${projectName}`;
this.expandItem(rootItem)

View File

@ -1,5 +1,3 @@
import { Promise, resolve, reject } from "bluebird";
/*********************************************************************
* Copyright (c) 2018 Red Hat, Inc.
*
@ -15,12 +13,12 @@ import { Promise, resolve, reject } from "bluebird";
export class TestWorkspaceUtil {
private waitRunningStatus(workspaceNamespace: string, workspaceName: string, attempt: number): Promise<void> {
private waitRunningStatus(workspaceNamespace: string, workspaceName: string, attempt: number): PromiseLike<void> {
const maximumAttempts: number = Cypress.env("TestWorkspaceUtil.waitRunningStatusAttempts");
const delayBetweenAttempts: number = Cypress.env("TestWorkspaceUtil.waitRunningStatusPollingEvery");
const expectedWorkspaceStatus: string = 'RUNNING';
return new Promise((resolve, reject) => {
return new Cypress.Promise((resolve:any, reject:any) => {
cy.request('GET', `/api/workspace/${workspaceNamespace}:${workspaceName}`)
.then(response => {
@ -50,7 +48,7 @@ export class TestWorkspaceUtil {
}
waitWorkspaceRunning(workspaceNamespace: string, workspaceName: string): Promise<void> {
waitWorkspaceRunning(workspaceNamespace: string, workspaceName: string): PromiseLike<void> {
let attempt: number = 0;
return this.waitRunningStatus(workspaceNamespace, workspaceName, attempt)
}

View File

@ -3738,6 +3738,11 @@
"loose-envify": "^1.0.0"
}
},
"inversify": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/inversify/-/inversify-5.0.1.tgz",
"integrity": "sha512-Ieh06s48WnEYGcqHepdsJUIJUXpwH5o5vodAX+DK2JA/gjy4EbEcQZxw+uFfzysmKjiLXGYwNG3qDZsKVMcINQ=="
},
"invert-kv": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz",
@ -5192,6 +5197,11 @@
"readable-stream": "^2.0.2"
}
},
"reflect-metadata": {
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
"integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg=="
},
"regenerate": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz",

View File

@ -18,5 +18,9 @@
"ts-loader": "^5.3.3",
"typescript": "^3.3.3",
"webpack": "^4.29.3"
},
"dependencies": {
"inversify": "^5.0.1",
"reflect-metadata": "^0.1.13"
}
}

View File

@ -4,8 +4,12 @@
"noImplicitAny": true,
"module": "es6",
"target": "es5",
"lib": ["es6", "dom"],
"jsx": "react",
"allowJs": true,
"types": ["cypress"]
"moduleResolution": "node",
"types": ["cypress", "reflect-metadata"],
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}