-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ TS-SELENIUM ] Investigating new typescript related test framework #13200
Changes from 54 commits
d706904
e4afc5b
3cb248e
ca8b301
e307ce4
8c2f2f5
13b64e3
269617f
79b5a09
aa98cff
bd596ca
15853ec
2dbc438
10f011f
e9fa3ff
6f24843
cc8beca
124e0cb
cbffa2f
6830399
3473987
292d32e
103fb74
508831e
6c9fdcf
3297b1f
0e414fc
edeff86
f52e833
2de6d1f
acfd277
fd8573c
571ee36
61d58bd
1d2673e
5aab39a
8bacf5e
5902195
37e4726
150145c
db6ba5f
be1d841
29d9856
fbcd9af
65d45e6
2042f73
dcf5a00
a9cd9e8
8a78567
d261298
3a4ae9e
48d5d0f
fa58f3c
b77621f
19e0434
708dde9
b4ce619
1302bdc
659d2e5
3e0223c
b25c53f
b3128c1
f4e5ca5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
## Requirements | ||
- node 8.x | ||
- "Chrome" browser 69.x or later | ||
|
||
## Default launch | ||
- npm install && npm test | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dashboard uses |
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These two commands are not enough. I miss information about how to run the app (maybe link to a different readme would be enough). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not the responsibility of this module to deploy Che. It just goes to the provided link and performs tests. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I completely agree with you. This is the reason why I suggested to just provide the link to the instructions. |
||
## Custom launch | ||
- Use environment variables which described in the **```'TestConstants.ts'```** file |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/********************************************************************* | ||
* Copyright (c) 2019 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 TestConstants = { | ||
/** | ||
* Base URL of the application which should be checked | ||
*/ | ||
TS_SELENIUM_BASE_URL: process.env.TS_SELENIUM_BASE_URL || "http://che-che.192.168.99.100.nip.io", | ||
|
||
/** | ||
* Run browser in "Headless" (hiden) mode, "false" by default. | ||
*/ | ||
TS_SELENIUM_HEADLESS: process.env.TS_SELENIUM_HEADLESS === 'true', | ||
|
||
/** | ||
* Browser width resolution, "1920" by default. | ||
*/ | ||
TS_SELENIUM_RESOLUTION_WIDTH: Number(process.env.TS_SELENIUM_BASE_URL) || 1920, | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here and in most other cases 2 or 3 blank lines are unnecessary and looks weird! |
||
/** | ||
* Browser height resolution, "1080" by default. | ||
*/ | ||
TS_SELENIUM_RESOLUTION_HEIGHT: Number(process.env.TS_SELENIUM_BASE_URL) || 1080, | ||
|
||
/** | ||
* Timeout in milliseconds waiting for workspace start, "240 000" by default. | ||
*/ | ||
TS_SELENIUM_START_WORKSPACE_TIMEOUT: Number(process.env.TS_SELENIUM_START_WORKSPACE_TIMEOUT) || 240000, | ||
|
||
/** | ||
* Timeout in milliseconds waiting for page load, "120 000" by default. | ||
*/ | ||
TS_SELENIUM_LOAD_PAGE_TIMEOUT: Number(process.env.TS_SELENIUM_LOAD_PAGE_TIMEOUT) || 120000, | ||
|
||
/** | ||
* Timeout in milliseconds waiting for language server initialization, "180 000" by default. | ||
*/ | ||
TS_SELENIUM_LANGUAGE_SERVER_START_TIMEOUT: Number(process.env.TS_SELENIUM_LANGUAGE_SERVER_START_TIMEOUT) || 180000, | ||
|
||
/** | ||
* Default timeout for most of the waitings, "20 000" by default. | ||
*/ | ||
TS_SELENIUM_DEFAULT_TIMEOUT: Number(process.env.TS_SELENIUM_DEFAULT_TIMEOUT) || 20000, | ||
|
||
/** | ||
* Default ammount of tries, "5" by default. | ||
*/ | ||
TS_SELENIUM_DEFAULT_ATTEMPTS: Number(process.env.TS_SELENIUM_DEFAULT_ATTEMPTS) || 5, | ||
|
||
/** | ||
* Default delay in milliseconds between tries, "1000" by default. | ||
*/ | ||
TS_SELENIUM_DEFAULT_POLLING: Number(process.env.TS_SELENIUM_DEFAULT_POLLING) || 1000, | ||
|
||
/** | ||
* Amount of tries for checking workspace status. | ||
*/ | ||
TS_SELENIUM_WORKSPACE_STATUS_ATTEMPTS: Number(process.env.TS_SELENIUM_WORKSPACE_STATUS_ATTEMPTS) || 90, | ||
|
||
/** | ||
* Delay in milliseconds between checking workspace status tries. | ||
*/ | ||
TS_SELENIUM_WORKSPACE_STATUS_POLLING: Number(process.env.TS_SELENIUM_WORKSPACE_STATUS_POLLING) || 10000 | ||
|
||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it is default value which valid for minikube Che. For customization may be used the "TS_SELENIUM_BASE_URL" environment variable There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i am not sure it that 192.168.99.100 default minikube value and nip.io suffix also can be changed it may be has many values for customizing. It may be a bit confuse our contributors. I guess something like localhost will be more clearer There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are a lot of variants, I just put one of them There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Couldn't we make that parameter as "mandatory", as we can agree there is not right "default" value? |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/********************************************************************* | ||
* Copyright (c) 2019 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 | ||
**********************************************************************/ | ||
import * as mocha from 'mocha'; | ||
import { Driver } from './Driver'; | ||
import { e2eContainer } from '../inversify.config'; | ||
import { TYPES } from '../inversify.types'; | ||
import * as fs from 'fs'; | ||
import { TestConstants } from '../TestConstants'; | ||
|
||
const driver: Driver = e2eContainer.get(TYPES.Driver); | ||
|
||
class CheReporter extends mocha.reporters.Spec { | ||
|
||
constructor(runner: mocha.Runner, options: mocha.MochaOptions) { | ||
super(runner, options); | ||
|
||
runner.on('start', async (test: mocha.Test) => { | ||
const launchInformation: string = | ||
`################## Launch Information ################## | ||
|
||
TS_SELENIUM_BASE_URL: ${TestConstants.TS_SELENIUM_BASE_URL} | ||
TS_SELENIUM_HEADLESS: ${TestConstants.TS_SELENIUM_HEADLESS} | ||
|
||
TS_SELENIUM_DEFAULT_ATTEMPTS: ${TestConstants.TS_SELENIUM_DEFAULT_ATTEMPTS} | ||
TS_SELENIUM_DEFAULT_POLLING: ${TestConstants.TS_SELENIUM_DEFAULT_POLLING} | ||
TS_SELENIUM_DEFAULT_TIMEOUT: ${TestConstants.TS_SELENIUM_DEFAULT_TIMEOUT} | ||
|
||
TS_SELENIUM_LANGUAGE_SERVER_START_TIMEOUT: ${TestConstants.TS_SELENIUM_LANGUAGE_SERVER_START_TIMEOUT} | ||
TS_SELENIUM_LOAD_PAGE_TIMEOUT: ${TestConstants.TS_SELENIUM_LOAD_PAGE_TIMEOUT} | ||
TS_SELENIUM_START_WORKSPACE_TIMEOUT: ${TestConstants.TS_SELENIUM_START_WORKSPACE_TIMEOUT} | ||
TS_SELENIUM_WORKSPACE_STATUS_ATTEMPTS: ${TestConstants.TS_SELENIUM_WORKSPACE_STATUS_ATTEMPTS} | ||
TS_SELENIUM_WORKSPACE_STATUS_POLLING: ${TestConstants.TS_SELENIUM_WORKSPACE_STATUS_POLLING} | ||
|
||
######################################################## | ||
` | ||
console.log(launchInformation) | ||
}) | ||
|
||
runner.on('end', async function (test: mocha.Test) { | ||
// ensure that fired events done | ||
await driver.get().sleep(5000) | ||
|
||
// close driver | ||
await driver.get().quit() | ||
}) | ||
|
||
runner.on('fail', async function (test: mocha.Test) { | ||
|
||
const reportDirPath: string = './report' | ||
const testFullTitle: string = test.fullTitle().replace(/\s/g, '_') | ||
const testTitle: string = test.title.replace(/\s/g, '_') | ||
|
||
const testReportDirPath: string = `${reportDirPath}/${testFullTitle}` | ||
const screenshotFileName: string = `${testReportDirPath}/screenshot-${testTitle}.png` | ||
const pageSourceFileName: string = `${testReportDirPath}/pagesource-${testTitle}.html` | ||
|
||
// create reporter dir if not exist | ||
await fs.exists(reportDirPath, async isDirExist => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am afraid, you have a race here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one is still valid, right @Ohrimenko1988 ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From Node.js v10.12 you can use recursive version of |
||
if (!isDirExist) { | ||
await fs.mkdir(reportDirPath, err => { | ||
if (err) { | ||
throw err | ||
} | ||
}) | ||
} | ||
}) | ||
|
||
// create dir for collected data if not exist | ||
await fs.exists(testReportDirPath, async isDirExist => { | ||
if (!isDirExist) { | ||
await fs.mkdir(testReportDirPath, err => { | ||
if (err) { | ||
throw err | ||
} | ||
}) | ||
} | ||
}) | ||
|
||
// take screenshot and write to file | ||
const screenshot: string = await driver.get().takeScreenshot(); | ||
const screenshotStream = fs.createWriteStream(screenshotFileName) | ||
screenshotStream.write(new Buffer(screenshot, 'base64')) | ||
screenshotStream.end() | ||
|
||
// take pagesource and write to file | ||
const pageSource: string = await driver.get().getPageSource() | ||
const pageSourceStream = fs.createWriteStream(pageSourceFileName) | ||
pageSourceStream.write(new Buffer(pageSource)) | ||
pageSourceStream.end() | ||
|
||
}) | ||
} | ||
} | ||
|
||
export = CheReporter; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/********************************************************************* | ||
* Copyright (c) 2019 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 | ||
**********************************************************************/ | ||
import 'chromedriver'; | ||
import 'reflect-metadata'; | ||
import { injectable, inject } from "inversify"; | ||
import { ThenableWebDriver, Builder } from "selenium-webdriver"; | ||
import { Driver } from './Driver'; | ||
import { Options } from 'selenium-webdriver/chrome'; | ||
import { TestConstants } from '../TestConstants'; | ||
|
||
@injectable() | ||
export class ChromeDriver implements Driver { | ||
private readonly driver: ThenableWebDriver; | ||
|
||
constructor() { | ||
const isHeadless: boolean = TestConstants.TS_SELENIUM_HEADLESS; | ||
let options: Options = new Options().addArguments('--no-sandbox') | ||
|
||
if (isHeadless) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe less code: let options = new Options().addArguments('--no-sandbox');
if (isHeadless) {
options = options.addArguments('headless'))
}
this.driver = new Builder()
.forBrowser('chrome')
.setChromeOptions(options)
.build(); |
||
options = options.addArguments('headless') | ||
} | ||
|
||
this.driver = new Builder() | ||
.forBrowser('chrome') | ||
.setChromeOptions(options) | ||
.build(); | ||
|
||
this.driver | ||
.manage() | ||
.window() | ||
.setSize(TestConstants.TS_SELENIUM_RESOLUTION_WIDTH, TestConstants.TS_SELENIUM_RESOLUTION_HEIGHT) | ||
} | ||
rhopp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
get(): ThenableWebDriver { | ||
return this.driver | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
/********************************************************************* | ||
* Copyright (c) 2019 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 | ||
**********************************************************************/ | ||
import { ThenableWebDriver } from "selenium-webdriver"; | ||
|
||
export interface Driver { | ||
get(): ThenableWebDriver | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the reason to return There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Ohrimenko1988 Is there a reason for this? |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/********************************************************************* | ||
* Copyright (c) 2019 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 | ||
**********************************************************************/ | ||
import { Container } from "inversify"; | ||
import { Driver } from "./driver/Driver"; | ||
import { TYPES, CLASSES } from "./inversify.types"; | ||
import { ChromeDriver } from "./driver/ChromeDriver"; | ||
import { DriverHelper } from "./utils/DriverHelper"; | ||
import { LoginPage } from "./pageobjects/login/LoginPage"; | ||
import { SingleUserLoginPage } from "./pageobjects/login/SingleUserLoginPage"; | ||
import { Dashboard } from "./pageobjects/dashboard/Dashboard"; | ||
import { Workspaces } from "./pageobjects/dashboard/Workspaces"; | ||
import { NewWorkspace } from "./pageobjects/dashboard/NewWorkspace"; | ||
import { WorkspaceDetails } from "./pageobjects/dashboard/workspace-details/WorkspaceDetails"; | ||
import { WorkspaceDetailsPlugins } from "./pageobjects/dashboard/workspace-details/WorkspaceDetailsPlugins"; | ||
import { Ide } from "./pageobjects/ide/Ide"; | ||
import { TestWorkspaceUtil } from "./utils/workspace/TestWorkspaceUtil"; | ||
import { ProjectTree } from "./pageobjects/ide/ProjectTree"; | ||
import { Editor } from "./pageobjects/ide/Editor"; | ||
|
||
const e2eContainer = new Container(); | ||
|
||
e2eContainer.bind<Driver>(TYPES.Driver).to(ChromeDriver).inSingletonScope(); | ||
e2eContainer.bind<LoginPage>(TYPES.LoginPage).to(SingleUserLoginPage).inSingletonScope(); | ||
|
||
e2eContainer.bind<DriverHelper>(CLASSES.DriverHelper).to(DriverHelper).inSingletonScope(); | ||
e2eContainer.bind<Dashboard>(CLASSES.Dashboard).to(Dashboard).inSingletonScope(); | ||
e2eContainer.bind<Workspaces>(CLASSES.Workspaces).to(Workspaces).inSingletonScope(); | ||
e2eContainer.bind<NewWorkspace>(CLASSES.NewWorkspace).to(NewWorkspace).inSingletonScope(); | ||
e2eContainer.bind<WorkspaceDetails>(CLASSES.WorkspaceDetails).to(WorkspaceDetails).inSingletonScope(); | ||
e2eContainer.bind<WorkspaceDetailsPlugins>(CLASSES.WorkspaceDetailsPlugins).to(WorkspaceDetailsPlugins).inSingletonScope(); | ||
e2eContainer.bind<Ide>(CLASSES.Ide).to(Ide).inSingletonScope(); | ||
e2eContainer.bind<TestWorkspaceUtil>(CLASSES.TestWorkspaceUtil).to(TestWorkspaceUtil).inSingletonScope(); | ||
e2eContainer.bind<ProjectTree>(CLASSES.ProjectTree).to(ProjectTree).inSingletonScope(); | ||
e2eContainer.bind<Editor>(CLASSES.Editor).to(Editor).inSingletonScope(); | ||
|
||
|
||
|
||
export { e2eContainer } |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/********************************************************************* | ||
* Copyright (c) 2019 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 TYPES = { | ||
Driver: Symbol.for("Driver"), | ||
LoginPage: Symbol.for("LoginPage") | ||
} | ||
|
||
const CLASSES = { | ||
DriverHelper: "DriverHelper", | ||
Dashboard: "Dashboard", | ||
Workspaces: "Workspaces", | ||
NewWorkspace: "NewWorkspace", | ||
WorkspaceDetails: "WorkspaceDetails", | ||
WorkspaceDetailsPlugins: "WorkspaceDetailsPlugins", | ||
Ide: "Ide", | ||
TestWorkspaceUtil: "TestWorkspaceUtil", | ||
ProjectTree: "ProjectTree", | ||
Editor: "Editor", | ||
} | ||
|
||
export { TYPES, CLASSES }; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--require ts-node/register | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I strongly suggest to avoid this magic and call TypeScript compiler ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I have seen this problem when trying to consume this project on our side. So I'm running it in this way:
and this is mocha.opts
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Katka92 We're going to merge this one as it is right now and we can do this change inm the future, if needed. |
||
--timeout 1200000 | ||
--reporter 'driver/CheReporter.ts' | ||
-u tdd | ||
--bail | ||
--spec tests/*.spec.ts | ||
rhopp marked this conversation as resolved.
Show resolved
Hide resolved
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How is this change related to this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Ohrimenko1988 are you going to address this?