├── junit
├── .gitignore
├── src
│ ├── test
│ │ ├── resources
│ │ │ └── specs
│ │ │ │ ├── shared
│ │ │ │ ├── common.gspec
│ │ │ │ ├── commonLayout.gspec
│ │ │ │ ├── calloutComponent.gspec
│ │ │ │ ├── galen-extras-rules.js
│ │ │ │ └── galen-extras-rules.gspec
│ │ │ │ ├── googlePageLayout.gspec
│ │ │ │ ├── cssPageLayout.gspec
│ │ │ │ ├── homePageLayout.gspec
│ │ │ │ └── javascriptPageLayout.gspec
│ │ └── java
│ │ │ └── sample
│ │ │ ├── layout
│ │ │ ├── HomeLayoutTest.java
│ │ │ ├── JavascriptLayoutTest.java
│ │ │ ├── CssLayoutTest.java
│ │ │ └── GoogleLayoutTest.java
│ │ │ └── util
│ │ │ ├── GalenBaseTest.java
│ │ │ └── junit
│ │ │ └── LabelledParameterized.java
│ └── main
│ │ └── resources
│ │ └── log4j.properties
├── build
│ └── classes
│ │ └── log4j.properties
├── README.md
├── config
└── pom.xml
├── testng
├── .gitignore
├── build
│ └── .gitignore
├── src
│ ├── test
│ │ ├── resources
│ │ │ └── specs
│ │ │ │ ├── shared
│ │ │ │ ├── common.gspec
│ │ │ │ ├── commonLayout.gspec
│ │ │ │ ├── calloutComponent.gspec
│ │ │ │ ├── galen-extras-rules.js
│ │ │ │ └── galen-extras-rules.gspec
│ │ │ │ ├── googlePageLayout.gspec
│ │ │ │ ├── cssPageLayout.gspec
│ │ │ │ ├── homePageLayout.gspec
│ │ │ │ └── javascriptPageLayout.gspec
│ │ └── java
│ │ │ ├── sample
│ │ │ └── layout
│ │ │ │ ├── HomeLayoutTest.java
│ │ │ │ ├── JavascriptLayoutTest.java
│ │ │ │ ├── CssLayoutTest.java
│ │ │ │ └── GoogleLayoutTest.java
│ │ │ └── util
│ │ │ └── testng
│ │ │ └── GalenBaseTest.java
│ └── main
│ │ └── resources
│ │ └── log4j.properties
├── README.md
├── config
└── pom.xml
├── javascript
├── testSuite
│ └── bootstrap
│ │ ├── README.MD
│ │ ├── specs
│ │ ├── shared
│ │ │ ├── common.gspec
│ │ │ ├── commonLayout.gspec
│ │ │ ├── calloutComponent.gspec
│ │ │ ├── galen-extras-rules.js
│ │ │ └── galen-extras-rules.gspec
│ │ ├── googlePageLayout.gspec
│ │ ├── cssPageLayout.gspec
│ │ ├── homePageLayout.gspec
│ │ └── javascriptPageLayout.gspec
│ │ ├── runSauceLabs.sh
│ │ ├── runGalenTests.sh
│ │ ├── galen.config
│ │ ├── basic.test
│ │ └── saucelabs.test
├── gulp
│ ├── test
│ │ ├── specs
│ │ │ ├── google_failing.gspec
│ │ │ ├── google_success1.gspec
│ │ │ └── google_success2.gspec
│ │ └── basics.js
│ ├── Gulpfile.js
│ └── package.json
├── node
│ ├── test
│ │ ├── specs
│ │ │ ├── google_failing.gspec
│ │ │ ├── google_success1.gspec
│ │ │ └── google_success2.gspec
│ │ └── basics.js
│ ├── README.MD
│ └── package.json
├── grunt
│ ├── gl.config.js
│ ├── test
│ │ ├── example-page.gspec
│ │ ├── example.test.js
│ │ └── galen_pages.js
│ ├── package.json
│ ├── Gruntfile.js
│ └── gl.js
├── testRunner
│ └── bootstrap
│ │ ├── specs
│ │ ├── shared
│ │ │ ├── common.gspec
│ │ │ ├── commonLayout.gspec
│ │ │ ├── calloutComponent.gspec
│ │ │ ├── galen-extras-rules.js
│ │ │ └── galen-extras-rules.gspec
│ │ ├── googlePageLayout.gspec
│ │ ├── cssPageLayout.gspec
│ │ ├── homePageLayout.gspec
│ │ └── javascriptPageLayout.gspec
│ │ ├── runGalenTests.sh
│ │ ├── pages
│ │ └── homePage.js
│ │ ├── bootstrap.test.js
│ │ └── init.js
├── runSauceLabs.sh
├── runCI.sh
└── README.MD
├── README.md
├── .gitignore
└── LICENSE
/junit/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 |
--------------------------------------------------------------------------------
/testng/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 |
--------------------------------------------------------------------------------
/testng/build/.gitignore:
--------------------------------------------------------------------------------
1 | /classes/
2 |
--------------------------------------------------------------------------------
/javascript/testSuite/bootstrap/README.MD:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Saucelabs
4 |
5 | For more about mobile platforms on Saucelabs, see https://docs.saucelabs.com/reference/platforms-configurator/
--------------------------------------------------------------------------------
/javascript/gulp/test/specs/google_failing.gspec:
--------------------------------------------------------------------------------
1 | @objects
2 | input css input[name=q]
3 | submit css input[type=submit]
4 |
5 | = Main section =
6 | input:
7 | below submit
--------------------------------------------------------------------------------
/javascript/gulp/test/specs/google_success1.gspec:
--------------------------------------------------------------------------------
1 | @objects
2 | input css input[name=q]
3 | submit css input[type=submit]
4 |
5 | = Main section =
6 | input:
7 | above submit
--------------------------------------------------------------------------------
/javascript/gulp/test/specs/google_success2.gspec:
--------------------------------------------------------------------------------
1 | @objects
2 | input css input[name=q]
3 | submit css input[type=submit]
4 |
5 | = Main section =
6 | input:
7 | above submit
--------------------------------------------------------------------------------
/javascript/node/test/specs/google_failing.gspec:
--------------------------------------------------------------------------------
1 | @objects
2 | input css input[name=q]
3 | submit css input[type=submit]
4 |
5 | = Main section =
6 | input:
7 | below submit
--------------------------------------------------------------------------------
/javascript/node/test/specs/google_success1.gspec:
--------------------------------------------------------------------------------
1 | @objects
2 | input css input[name=q]
3 | submit css input[type=submit]
4 |
5 | = Main section =
6 | input:
7 | above submit
--------------------------------------------------------------------------------
/javascript/node/test/specs/google_success2.gspec:
--------------------------------------------------------------------------------
1 | @objects
2 | input css input[name=q]
3 | submit css input[type=submit]
4 |
5 | = Main section =
6 | input:
7 | above submit
--------------------------------------------------------------------------------
/junit/src/test/resources/specs/shared/common.gspec:
--------------------------------------------------------------------------------
1 |
2 | @objects
3 | navbar .navbar
4 | header .navbar-header
5 | item-* .navbar-collapse .nav li
6 | menubar-left .sidebar-left
7 | content #content
--------------------------------------------------------------------------------
/testng/src/test/resources/specs/shared/common.gspec:
--------------------------------------------------------------------------------
1 |
2 | @objects
3 | navbar .navbar
4 | header .navbar-header
5 | item-* .navbar-collapse .nav li
6 | menubar-left .sidebar-left
7 | content #content
--------------------------------------------------------------------------------
/javascript/grunt/gl.config.js:
--------------------------------------------------------------------------------
1 | config.set({"url":"http://example.com/","devices":{"desktop":{"deviceName":"desktop","browser":"firefox","size":"1280x800"},"tablet":{"deviceName":"tablet","browser":"firefox","size":"768x576"}}});
2 |
--------------------------------------------------------------------------------
/javascript/testRunner/bootstrap/specs/shared/common.gspec:
--------------------------------------------------------------------------------
1 |
2 | @objects
3 | navbar .navbar
4 | header .navbar-header
5 | item-* .navbar-collapse .nav li
6 | menubar-left .sidebar-left
7 | content #content
--------------------------------------------------------------------------------
/javascript/testSuite/bootstrap/specs/shared/common.gspec:
--------------------------------------------------------------------------------
1 |
2 | @objects
3 | navbar .navbar
4 | header .navbar-header
5 | item-* .navbar-collapse .nav li
6 | menubar-left .sidebar-left
7 | content #content
--------------------------------------------------------------------------------
/javascript/testSuite/bootstrap/runSauceLabs.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | currentDir=$( pwd )
4 | websiteUrl='http://getbootstrap.com'
5 |
6 | galen test saucelabs.test -DwebsiteUrl=${websiteUrl} --htmlreport ../../reports/bootstrap/saucelabs
7 | open ../../reports/bootstrap/saucelabs/report.html
--------------------------------------------------------------------------------
/javascript/grunt/test/example-page.gspec:
--------------------------------------------------------------------------------
1 | @objects
2 | label css h1
3 | paragraph css p
4 |
5 | = Main section =
6 | label:
7 | visible
8 | above paragraph
9 |
10 | paragraph:
11 | visible
12 | below label
13 |
--------------------------------------------------------------------------------
/javascript/node/README.MD:
--------------------------------------------------------------------------------
1 | # Galen samples for Node
2 |
3 |
4 | ## Setup
5 |
6 | ```bash
7 | npm i
8 |
9 | ```
10 |
11 | ## Execution
12 |
13 | ```
14 | npm run galen -- check test/specs/google_success1.gspec --url 'https://www.google.com' --size '1280x800' --htmlreport dist/galen-report
15 | ```
--------------------------------------------------------------------------------
/javascript/testRunner/bootstrap/runGalenTests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | currentDir=$( pwd )
4 | websiteUrl='http://getbootstrap.com'
5 |
6 | galen test . --htmlreport ../../reports/bootstrap/testrunner -Dwebdriver.chrome.driver=/opt/dev/chromedriver
7 | open ../../reports/bootstrap/testrunner/report.html
8 |
--------------------------------------------------------------------------------
/junit/src/test/resources/specs/googlePageLayout.gspec:
--------------------------------------------------------------------------------
1 |
2 | @objects
3 | search-input #lst-ib
4 | search-results #ires
5 |
6 | # concrete layout tests
7 |
8 | = Search input visible =
9 | search-input:
10 | visible
11 |
12 | = Show search results =
13 | search-results:
14 | visible
--------------------------------------------------------------------------------
/testng/README.md:
--------------------------------------------------------------------------------
1 | # Galen samples for Maven and TestNG
2 |
3 | A showcase of Maven + TestNG + Galen usage
4 |
5 | Jenkins Sample Build: [](https://martinreinhardt-online.de/jenkins/job/Galen/job/Galen_sample_TestNG/)
6 |
--------------------------------------------------------------------------------
/testng/src/test/resources/specs/googlePageLayout.gspec:
--------------------------------------------------------------------------------
1 |
2 | @objects
3 | search-input #lst-ib
4 | search-results #ires
5 |
6 | # concrete layout tests
7 |
8 | = Search input visible =
9 | search-input:
10 | visible
11 |
12 | = Show search results =
13 | search-results:
14 | visible
--------------------------------------------------------------------------------
/javascript/grunt/test/example.test.js:
--------------------------------------------------------------------------------
1 | load('../gl.js');
2 |
3 | forAll(config.getDevices(), function (device) {
4 | test('Example page on ' + device.deviceName, function () {
5 | gl.openPage(device, config.getProjectPage());
6 |
7 | gl.runSpecFile(device, './test/example-page.gspec');
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/javascript/testRunner/bootstrap/specs/googlePageLayout.gspec:
--------------------------------------------------------------------------------
1 |
2 | @objects
3 | search-input #lst-ib
4 | search-results #ires
5 |
6 | # concrete layout tests
7 |
8 | = Search input visible =
9 | search-input:
10 | visible
11 |
12 | = Show search results =
13 | search-results:
14 | visible
--------------------------------------------------------------------------------
/javascript/testSuite/bootstrap/runGalenTests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | currentDir=$( pwd )
4 | websiteUrl='http://getbootstrap.com'
5 |
6 | galen test basic.test -DwebsiteUrl=${websiteUrl} --htmlreport ../../reports/bootstrap/local -Dwebdriver.chrome.driver=/opt/dev/chromedriver
7 | open ../../reports/bootstrap/local/report.html
--------------------------------------------------------------------------------
/javascript/testSuite/bootstrap/specs/googlePageLayout.gspec:
--------------------------------------------------------------------------------
1 |
2 | @objects
3 | search-input #lst-ib
4 | search-results #ires
5 |
6 | # concrete layout tests
7 |
8 | = Search input visible =
9 | search-input:
10 | visible
11 |
12 | = Show search results =
13 | search-results:
14 | visible
--------------------------------------------------------------------------------
/javascript/runSauceLabs.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | currentDir=$( pwd )
4 | websiteUrl='http://getbootstrap.com'
5 |
6 | cd testSuite
7 |
8 | cd bootstrap
9 | galen test saucelabs.test -DwebsiteUrl=${websiteUrl} --htmlreport ../../reports/bootstrap/saucelabsTestsuite --testngreport ../../reports/bootstrap/saucelabsTestsuite/testng.xml
10 |
--------------------------------------------------------------------------------
/javascript/node/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "galen_samples",
3 | "version": "1.0.0",
4 | "description": "",
5 | "scripts": {
6 | "galen": "galen"
7 | },
8 | "author": {
9 | "name": "Martin Reinhardt"
10 | },
11 | "license": "MIT",
12 | "devDependencies": {
13 | "galenframework-cli": "2.3.2"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/junit/src/test/resources/specs/cssPageLayout.gspec:
--------------------------------------------------------------------------------
1 | @import shared/common.gspec
2 |
3 | @objects
4 | css-hint-* div.bs-callout
5 |
6 | # common layout checks
7 | @import shared/commonLayout.gspec
8 |
9 | # concrete layout tests
10 |
11 | = code snippets should render correct =
12 | css-hint-*:
13 | component shared/calloutComponent.gspec
--------------------------------------------------------------------------------
/testng/src/test/resources/specs/cssPageLayout.gspec:
--------------------------------------------------------------------------------
1 | @import shared/common.gspec
2 |
3 | @objects
4 | css-hint-* div.bs-callout
5 |
6 | # common layout checks
7 | @import shared/commonLayout.gspec
8 |
9 | # concrete layout tests
10 |
11 | = code snippets should render correct =
12 | css-hint-*:
13 | component shared/calloutComponent.gspec
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Galen Samples
2 | =====================================
3 |
4 | This project is used in order to demonstrate the features of [Galen Framework](http://galenframework.com) and the power of layout tests
5 |
6 | Here you find two sample projects:
7 | * Using [TestNG](testng)
8 | * Using [JUnit](junit)
9 | * Using [JavaScript](javascript)
10 |
--------------------------------------------------------------------------------
/javascript/testRunner/bootstrap/specs/cssPageLayout.gspec:
--------------------------------------------------------------------------------
1 | @import shared/common.gspec
2 |
3 | @objects
4 | css-hint-* div.bs-callout
5 |
6 | # common layout checks
7 | @import shared/commonLayout.gspec
8 |
9 | # concrete layout tests
10 |
11 | = code snippets should render correct =
12 | css-hint-*:
13 | component shared/calloutComponent.gspec
--------------------------------------------------------------------------------
/javascript/testSuite/bootstrap/specs/cssPageLayout.gspec:
--------------------------------------------------------------------------------
1 | @import shared/common.gspec
2 |
3 | @objects
4 | css-hint-* div.bs-callout
5 |
6 | # common layout checks
7 | @import shared/commonLayout.gspec
8 |
9 | # concrete layout tests
10 |
11 | = code snippets should render correct =
12 | css-hint-*:
13 | component shared/calloutComponent.gspec
--------------------------------------------------------------------------------
/javascript/testRunner/bootstrap/pages/homePage.js:
--------------------------------------------------------------------------------
1 | this.HomePage = function (driver) {
2 | GalenPages.extendPage(this, driver, {
3 | goToGitHubButton: "(//*[contains(@class,'bs-docs-featurette')]//a[contains(@class,'btn')])[1]",
4 | goToExpoButton: "(//*[contains(@class,'bs-docs-featurette')]//a[contains(@class,'btn')])[2]"
5 | });
6 | };
7 |
--------------------------------------------------------------------------------
/javascript/gulp/Gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp'),
2 | gulpGalen = require('gulp-galenframework');
3 |
4 | gulp.task("test:galen", function (done) {
5 | gulp.src('test/specs/**/google*.gspec').pipe(gulpGalen.check({
6 | url: 'https://www.google.com',
7 | cwd: 'test/galen/',
8 | size: '1280x800'
9 | }, done));
10 | });
--------------------------------------------------------------------------------
/junit/src/test/resources/specs/homePageLayout.gspec:
--------------------------------------------------------------------------------
1 | @import shared/common.gspec
2 |
3 | @objects
4 | bootstrap-logo span.bs-docs-booticon
5 |
6 | # common layout checks
7 | @import shared/commonLayout.gspec
8 |
9 | # concrete layout tests
10 |
11 | = Bootstrap logo should be visible =
12 | bootstrap-logo:
13 | | should be squared
14 | visible
--------------------------------------------------------------------------------
/testng/src/test/resources/specs/homePageLayout.gspec:
--------------------------------------------------------------------------------
1 | @import shared/common.gspec
2 |
3 | @objects
4 | bootstrap-logo span.bs-docs-booticon
5 |
6 | # common layout checks
7 | @import shared/commonLayout.gspec
8 |
9 | # concrete layout tests
10 |
11 | = Bootstrap logo should be visible =
12 | bootstrap-logo:
13 | | should be squared
14 | visible
--------------------------------------------------------------------------------
/javascript/testRunner/bootstrap/specs/homePageLayout.gspec:
--------------------------------------------------------------------------------
1 | @import shared/common.gspec
2 |
3 | @objects
4 | bootstrap-logo span.bs-docs-booticon
5 |
6 | # common layout checks
7 | @import shared/commonLayout.gspec
8 |
9 | # concrete layout tests
10 |
11 | = Bootstrap logo should be visible =
12 | bootstrap-logo:
13 | | should be squared
14 | visible
--------------------------------------------------------------------------------
/javascript/testSuite/bootstrap/specs/homePageLayout.gspec:
--------------------------------------------------------------------------------
1 | @import shared/common.gspec
2 |
3 | @objects
4 | bootstrap-logo span.bs-docs-booticon
5 |
6 | # common layout checks
7 | @import shared/commonLayout.gspec
8 |
9 | # concrete layout tests
10 |
11 | = Bootstrap logo should be visible =
12 | bootstrap-logo:
13 | | should be squared
14 | visible
--------------------------------------------------------------------------------
/javascript/gulp/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gulp-galen-sample",
3 | "version": "0.1.0",
4 | "private": true,
5 | "keywords": [
6 | "gulp",
7 | "galen"
8 | ],
9 | "author": {
10 | "name": "Martin Reinhardt"
11 | },
12 | "license": "MIT",
13 | "devDependencies": {
14 | "gulp": "^3.9.1",
15 | "gulp-galenframework": "^2.2.4"
16 | },
17 | "scripts": {
18 | "test": "npm install && gulp test:galen"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/javascript/testSuite/bootstrap/galen.config:
--------------------------------------------------------------------------------
1 | # Range approximation
2 | galen.range.approximation=3
3 |
4 | # Fullscreen screenshots
5 | galen.browser.screenshots.fullPage = true
6 |
7 | # Exit with fail code in case of any failures
8 | galen.use.fail.exit.code = true
9 |
10 | # Default value for tolerance in image spec
11 | galen.spec.image.tolerance = 30
12 |
13 | # Default value for error rate in image spec
14 | galen.spec.image.error = 0px
15 |
16 |
--------------------------------------------------------------------------------
/javascript/grunt/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "grunt-galen-sample",
3 | "version": "0.1.0",
4 | "private": true,
5 | "keywords": [
6 | "grunt",
7 | "galen"
8 | ],
9 | "author": {
10 | "name": "Martin Reinhardt"
11 | },
12 | "license": "MIT",
13 | "devDependencies": {
14 | "grunt": "^0.4.5",
15 | "grunt-cli": "^0.1.13",
16 | "grunt-galenframework": "^2.2.4",
17 | "load-grunt-tasks": "^3.5.0"
18 | },
19 | "scripts": {
20 | "test": "npm install && grunt"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/junit/src/test/resources/specs/javascriptPageLayout.gspec:
--------------------------------------------------------------------------------
1 | @import shared/common.gspec
2 |
3 | @objects
4 | js-code-snippet-* div.bs-callout
5 | ad-container #carbonads-container
6 | ad .carbonad
7 |
8 | # common layout checks
9 | @import shared/commonLayout.gspec
10 |
11 | # concrete layout tests
12 |
13 | = Code snippets should be vertical aligned =
14 | @forEach [js-code-snippet-*] as snippet, next as nextSnippet
15 | ${snippet}:
16 | aligned vertically left ${nextSnippet}
17 |
18 | = Ad should be centered =
19 | ad:
20 | centered horizontally on ad-container
21 |
--------------------------------------------------------------------------------
/testng/src/test/resources/specs/javascriptPageLayout.gspec:
--------------------------------------------------------------------------------
1 | @import shared/common.gspec
2 |
3 | @objects
4 | js-code-snippet-* div.bs-callout
5 | ad-container #carbonads-container
6 | ad .carbonad
7 |
8 | # common layout checks
9 | @import shared/commonLayout.gspec
10 |
11 | # concrete layout tests
12 |
13 | = Code snippets should be vertical aligned =
14 | @forEach [js-code-snippet-*] as snippet, next as nextSnippet
15 | ${snippet}:
16 | aligned vertically left ${nextSnippet}
17 |
18 | = Ad should be centered =
19 | ad:
20 | centered horizontally on ad-container
21 |
--------------------------------------------------------------------------------
/javascript/testRunner/bootstrap/specs/javascriptPageLayout.gspec:
--------------------------------------------------------------------------------
1 | @import shared/common.gspec
2 |
3 | @objects
4 | js-code-snippet-* div.bs-callout
5 | ad-container #carbonads-container
6 | ad .carbonad
7 |
8 | # common layout checks
9 | @import shared/commonLayout.gspec
10 |
11 | # concrete layout tests
12 |
13 | = Code snippets should be vertical aligned =
14 | @forEach [js-code-snippet-*] as snippet, next as nextSnippet
15 | ${snippet}:
16 | aligned vertically left ${nextSnippet}
17 |
18 | = Ad should be centered =
19 | ad:
20 | centered horizontally on ad-container
21 |
--------------------------------------------------------------------------------
/javascript/testSuite/bootstrap/specs/javascriptPageLayout.gspec:
--------------------------------------------------------------------------------
1 | @import shared/common.gspec
2 |
3 | @objects
4 | js-code-snippet-* div.bs-callout
5 | ad-container #carbonads-container
6 | ad .carbonad
7 |
8 | # common layout checks
9 | @import shared/commonLayout.gspec
10 |
11 | # concrete layout tests
12 |
13 | = Code snippets should be vertical aligned =
14 | @forEach [js-code-snippet-*] as snippet, next as nextSnippet
15 | ${snippet}:
16 | aligned vertically left ${nextSnippet}
17 |
18 | = Ad should be centered =
19 | ad:
20 | centered horizontally on ad-container
21 |
--------------------------------------------------------------------------------
/junit/src/test/resources/specs/shared/commonLayout.gspec:
--------------------------------------------------------------------------------
1 | @import galen-extras-rules.gspec
2 |
3 | = Overall layout =
4 |
5 | content:
6 | visible
7 | navbar.header:
8 | visible
9 | content:
10 | below navbar
11 |
12 | = navigation =
13 |
14 | @on mobile
15 | navbar.item-*:
16 | absent
17 |
18 | @on desktop
19 | navbar.item-*:
20 | visible
21 |
22 | = Content should fit to screen size =
23 |
24 | @on mobile
25 | content:
26 | width 100% of screen/width
27 |
28 | @on desktop
29 | content:
30 | width 80 to 90% of screen/width
31 |
--------------------------------------------------------------------------------
/testng/src/test/resources/specs/shared/commonLayout.gspec:
--------------------------------------------------------------------------------
1 | @import galen-extras-rules.gspec
2 |
3 | = Overall layout =
4 |
5 | content:
6 | visible
7 | navbar.header:
8 | visible
9 | content:
10 | below navbar
11 |
12 | = navigation =
13 |
14 | @on mobile
15 | navbar.item-*:
16 | absent
17 |
18 | @on desktop
19 | navbar.item-*:
20 | visible
21 |
22 | = Content should fit to screen size =
23 |
24 | @on mobile
25 | content:
26 | width 100% of screen/width
27 |
28 | @on desktop
29 | content:
30 | width 80 to 90% of screen/width
31 |
--------------------------------------------------------------------------------
/javascript/testSuite/bootstrap/specs/shared/commonLayout.gspec:
--------------------------------------------------------------------------------
1 | @import galen-extras-rules.gspec
2 |
3 | = Overall layout =
4 |
5 | content:
6 | visible
7 | navbar.header:
8 | visible
9 | content:
10 | below navbar
11 |
12 | = navigation =
13 |
14 | @on mobile
15 | navbar.item-*:
16 | absent
17 |
18 | @on desktop
19 | navbar.item-*:
20 | visible
21 |
22 | = Content should fit to screen size =
23 |
24 | @on mobile
25 | content:
26 | width 100% of screen/width
27 |
28 | @on desktop
29 | content:
30 | width 80 to 90% of screen/width
31 |
--------------------------------------------------------------------------------
/javascript/testRunner/bootstrap/specs/shared/commonLayout.gspec:
--------------------------------------------------------------------------------
1 | @import galen-extras-rules.gspec
2 |
3 | = Overall layout =
4 |
5 | content:
6 | visible
7 | navbar.header:
8 | visible
9 | content:
10 | below navbar
11 |
12 | = navigation =
13 |
14 | @on mobile
15 | navbar.item-*:
16 | absent
17 |
18 | @on desktop
19 | navbar.item-*:
20 | visible
21 |
22 | = Content should fit to screen size =
23 |
24 | @on mobile
25 | content:
26 | width 100% of screen/width
27 |
28 | @on desktop
29 | content:
30 | width 80 to 90% of screen/width
31 |
--------------------------------------------------------------------------------
/testng/src/test/java/sample/layout/HomeLayoutTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package sample.layout;
5 |
6 | import java.util.Arrays;
7 |
8 | import org.testng.annotations.Test;
9 |
10 | import util.testng.GalenBaseTest;
11 |
12 | /**
13 | * @author mreinhardt
14 | *
15 | */
16 | public class HomeLayoutTest extends GalenBaseTest {
17 |
18 | @Test(dataProvider = "devices")
19 | public void shouldShowCorrectBaseLayout(final TestDevice device) throws Exception {
20 | verifyPage("/",
21 | device,
22 | "/specs/homePageLayout.gspec",
23 | Arrays.asList("Homepage", "Bootstrap"));
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/javascript/runCI.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | currentDir=$( pwd )
4 | websiteUrl='http://getbootstrap.com'
5 |
6 | cd testSuite
7 |
8 | cd bootstrap
9 | galen test basic.test -DwebsiteUrl=${websiteUrl} --htmlreport ../../reports/bootstrap/testsuite --testngreport ../../reports/bootstrap/testsuite/testng.xml -Dwebdriver.chrome.driver=/opt/dev/tools/chromedriver
10 |
11 | cd ../../testRunner
12 |
13 | cd bootstrap
14 | galen test . --htmlreport ../../reports/bootstrap/testrunner/ --testngreport ../../reports/bootstrap/testrunner/testng.xml -Dwebdriver.chrome.driver=/opt/dev/tools/chromedriver
15 |
16 | cd ../../gulp
17 | npm test
18 |
19 | cd ../../grunt
20 | npm test
21 |
--------------------------------------------------------------------------------
/javascript/grunt/test/galen_pages.js:
--------------------------------------------------------------------------------
1 | this.SubmitPage = function (driver) {
2 | GalenPages.extendPage(this, driver, "Submit Page", {
3 | nameTextfield: "xpath: //*[@id='content']/div/input", // xpath locator
4 | submitButton: "xpath: //*[@id='content']/div/a" // xpath locator
5 |
6 | });
7 | };
8 |
9 |
10 | test("Home page test", function () {
11 | var driver = createDriver("http://samples.galenframework.com/tutorial-color-scheme/tutorial.html", "1400x1100", "firefox");
12 |
13 | var submitPage = new SubmitPage(driver);
14 |
15 | submitPage.nameTextfield.typeText("Something");
16 | submitPage.submitButton.click();
17 |
18 | driver.close();
19 |
20 | });
21 |
--------------------------------------------------------------------------------
/testng/src/test/java/sample/layout/JavascriptLayoutTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package sample.layout;
5 |
6 | import java.util.Arrays;
7 |
8 | import org.testng.annotations.Test;
9 |
10 | import util.testng.GalenBaseTest;
11 |
12 | /**
13 | * @author mreinhardt
14 | *
15 | */
16 | public class JavascriptLayoutTest extends GalenBaseTest {
17 |
18 | @Test(dataProvider = "devices")
19 | public void shouldShowCorrectBaseLayout(final TestDevice device) throws Exception {
20 | verifyPage("/javascript",
21 | device,
22 | "/specs/javascriptPageLayout.gspec",
23 | Arrays.asList("Javascript", "Bootstrap"));
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/junit/src/test/java/sample/layout/HomeLayoutTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package sample.layout;
5 |
6 | import org.junit.Test;
7 | import sample.util.GalenBaseTest;
8 |
9 | import java.util.Arrays;
10 |
11 | /**
12 | * @author mreinhardt
13 | */
14 | public class HomeLayoutTest extends GalenBaseTest {
15 |
16 | /**
17 | * @param pTestDevice
18 | */
19 | public HomeLayoutTest(TestDevice pTestDevice) {
20 | super(pTestDevice);
21 | }
22 |
23 | @Test
24 | public void shouldShowCorrectBaseLayout() throws Exception {
25 | verifyPage("/", "/specs/homePageLayout.gspec", Arrays.asList("Homepage", "Bootstrap"));
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/junit/build/classes/log4j.properties:
--------------------------------------------------------------------------------
1 | log4j.rootLogger=INFO,console,file
2 | # disable hibernate debugging logging
3 | log4j.logger.org.hibernate=ERROR
4 |
5 | #console
6 | log4j.appender.console=org.apache.log4j.ConsoleAppender
7 | log4j.appender.console.Threshold=ERROR
8 | log4j.appender.console.layout=org.apache.log4j.PatternLayout
9 | log4j.appender.MeinConsoleAppender.layout.ConversionPattern=%d{ISO8601} [%-5p] %-12c: %m%n
10 |
11 | #output in .log
12 | log4j.appender.file=org.apache.log4j.RollingFileAppender
13 | log4j.appender.file.file=logs/galen.log
14 | log4j.appender.file.layout=org.apache.log4j.PatternLayout
15 | log4j.appender.file.layout.ConversionPattern=%d{ISO8601} [%-5p] %-12c: %m%n
16 |
--------------------------------------------------------------------------------
/junit/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | log4j.rootLogger=INFO,console,file
2 | # disable hibernate debugging logging
3 | log4j.logger.org.hibernate=ERROR
4 |
5 | #console
6 | log4j.appender.console=org.apache.log4j.ConsoleAppender
7 | log4j.appender.console.Threshold=ERROR
8 | log4j.appender.console.layout=org.apache.log4j.PatternLayout
9 | log4j.appender.MeinConsoleAppender.layout.ConversionPattern=%d{ISO8601} [%-5p] %-12c: %m%n
10 |
11 | #output in .log
12 | log4j.appender.file=org.apache.log4j.RollingFileAppender
13 | log4j.appender.file.file=logs/galen.log
14 | log4j.appender.file.layout=org.apache.log4j.PatternLayout
15 | log4j.appender.file.layout.ConversionPattern=%d{ISO8601} [%-5p] %-12c: %m%n
16 |
--------------------------------------------------------------------------------
/testng/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | log4j.rootLogger=INFO,console,file
2 | # disable hibernate debugging logging
3 | log4j.logger.org.hibernate=ERROR
4 |
5 | #console
6 | log4j.appender.console=org.apache.log4j.ConsoleAppender
7 | log4j.appender.console.Threshold=ERROR
8 | log4j.appender.console.layout=org.apache.log4j.PatternLayout
9 | log4j.appender.MeinConsoleAppender.layout.ConversionPattern=%d{ISO8601} [%-5p] %-12c: %m%n
10 |
11 | #output in .log
12 | log4j.appender.file=org.apache.log4j.RollingFileAppender
13 | log4j.appender.file.file=logs/galen.log
14 | log4j.appender.file.layout=org.apache.log4j.PatternLayout
15 | log4j.appender.file.layout.ConversionPattern=%d{ISO8601} [%-5p] %-12c: %m%n
16 |
--------------------------------------------------------------------------------
/javascript/testRunner/bootstrap/bootstrap.test.js:
--------------------------------------------------------------------------------
1 | load("init.js");
2 | load("pages/homePage.js");
3 |
4 | testOnAllDevices("Bootstrap homepage", "/", function (driver, device) {
5 | var homePage = new HomePage(driver).waitForIt();
6 | checkLayout(driver, "specs/homePageLayout.gspec", device.tags);
7 | homePage.goToExpoButton().click();
8 | });
9 |
10 | testOnDeviceAndBrowsers(devices.mobile, "Bootstrap CSS page", "/css/", function (driver, device, browser) {
11 | checkLayout(driver, "specs/cssPageLayout.gspec", device.tags);
12 | });
13 |
14 | testOnAllDevicesAndBrowsers("Bootstrap JS page ", "/javascript/", function (driver, device, browser) {
15 | checkLayout(driver, "specs/javascriptPageLayout.gspec", device.tags);
16 | });
17 |
--------------------------------------------------------------------------------
/junit/src/test/java/sample/layout/JavascriptLayoutTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package sample.layout;
5 |
6 | import org.junit.Test;
7 | import sample.util.GalenBaseTest;
8 |
9 | import java.util.Arrays;
10 |
11 | /**
12 | * @author mreinhardt
13 | */
14 | public class JavascriptLayoutTest extends GalenBaseTest {
15 |
16 | /**
17 | * @param pTestDevice
18 | */
19 | public JavascriptLayoutTest(TestDevice pTestDevice) {
20 | super(pTestDevice);
21 | }
22 |
23 | @Test
24 | public void shouldShowCorrectBaseLayout() throws Exception {
25 | verifyPage("/javascript",
26 | "/specs/javascriptPageLayout.gspec",
27 | Arrays.asList("Javascript", "Bootstrap"));
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/junit/src/test/resources/specs/shared/calloutComponent.gspec:
--------------------------------------------------------------------------------
1 |
2 | @objects
3 | heading h4
4 | text-* p
5 |
6 | = callout = on phone device
7 | @on phone
8 | heading:
9 | inside parent 10px top left
10 | width 90 to 100% of screen/width
11 | text-*:
12 | inside parent 10px top left
13 | width 90 to 100% of screen/width
14 |
15 | @on tablet
16 | heading:
17 | inside parent 10px top left
18 | width 80 to 90% of screen/width
19 | text-*:
20 | inside parent 10px top left
21 | width 80 to 90% of screen/width
22 |
23 |
24 | @on desktop
25 | heading:
26 | inside: parent 10px top left
27 | width: 75 to 85% of screen/width
28 | text-*:
29 | inside: parent 10px top left
30 | width: 75 to 85% of screen/width
31 |
--------------------------------------------------------------------------------
/testng/src/test/resources/specs/shared/calloutComponent.gspec:
--------------------------------------------------------------------------------
1 |
2 | @objects
3 | heading h4
4 | text-* p
5 |
6 | = callout = on phone device
7 | @on phone
8 | heading:
9 | inside parent 10px top left
10 | width 90 to 100% of screen/width
11 | text-*:
12 | inside parent 10px top left
13 | width 90 to 100% of screen/width
14 |
15 | @on tablet
16 | heading:
17 | inside parent 10px top left
18 | width 80 to 90% of screen/width
19 | text-*:
20 | inside parent 10px top left
21 | width 80 to 90% of screen/width
22 |
23 |
24 | @on desktop
25 | heading:
26 | inside: parent 10px top left
27 | width: 75 to 85% of screen/width
28 | text-*:
29 | inside: parent 10px top left
30 | width: 75 to 85% of screen/width
31 |
--------------------------------------------------------------------------------
/javascript/testSuite/bootstrap/specs/shared/calloutComponent.gspec:
--------------------------------------------------------------------------------
1 |
2 | @objects
3 | heading h4
4 | text-* p
5 |
6 | = callout = on phone device
7 | @on phone
8 | heading:
9 | inside parent 10px top left
10 | width 90 to 100% of screen/width
11 | text-*:
12 | inside parent 10px top left
13 | width 90 to 100% of screen/width
14 |
15 | @on tablet
16 | heading:
17 | inside parent 10px top left
18 | width 80 to 90% of screen/width
19 | text-*:
20 | inside parent 10px top left
21 | width 80 to 90% of screen/width
22 |
23 |
24 | @on desktop
25 | heading:
26 | inside: parent 10px top left
27 | width: 75 to 85% of screen/width
28 | text-*:
29 | inside: parent 10px top left
30 | width: 75 to 85% of screen/width
31 |
--------------------------------------------------------------------------------
/javascript/testRunner/bootstrap/specs/shared/calloutComponent.gspec:
--------------------------------------------------------------------------------
1 |
2 | @objects
3 | heading h4
4 | text-* p
5 |
6 | = callout = on phone device
7 | @on phone
8 | heading:
9 | inside parent 10px top left
10 | width 90 to 100% of screen/width
11 | text-*:
12 | inside parent 10px top left
13 | width 90 to 100% of screen/width
14 |
15 | @on tablet
16 | heading:
17 | inside parent 10px top left
18 | width 80 to 90% of screen/width
19 | text-*:
20 | inside parent 10px top left
21 | width 80 to 90% of screen/width
22 |
23 |
24 | @on desktop
25 | heading:
26 | inside: parent 10px top left
27 | width: 75 to 85% of screen/width
28 | text-*:
29 | inside: parent 10px top left
30 | width: 75 to 85% of screen/width
31 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 |
3 | # Mobile Tools for Java (J2ME)
4 | .mtj.tmp/
5 |
6 | # Package Files #
7 | *.jar
8 | *.war
9 | *.ear
10 |
11 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
12 | hs_err_pid*
13 |
14 | testng/test-output/*
15 | testng/.project
16 | testng/.settings/*
17 | testng/.classpath
18 | testng/logs/*
19 | testng/build/classes/*
20 |
21 | junit/.project
22 | junit/.classpath
23 | junit/.settings/*
24 | junit/test-output/*
25 | junit/logs/*
26 | junit/build/classes/*
27 |
28 | reports/*
29 |
30 | javascript/testRunner/bootstrap/reports/*
31 | javascript/reports/*
32 | javascript/node/*.log
33 | javascript/node/dist/
34 | javascript/node/node_modules/
35 | javascript/grunt/node_modules/
36 | javascript/gulp/node_modules/
37 |
38 | ## IDEA
39 | .idea/*
40 | javascript/*.iml
41 | junit/*.iml
42 | testng/*.iml
43 |
--------------------------------------------------------------------------------
/junit/README.md:
--------------------------------------------------------------------------------
1 | # Galen samples for Maven and JUnit
2 |
3 | A showcase of Maven + JUnit + Galen usage
4 |
5 | Jenkins Sample Build: [](https://martinreinhardt-online.de/jenkins/job/Galen/job/Galen_sample_JUnit/)
6 |
7 | ## Steps touse this sample for your own
8 |
9 | You need Maven 3+ installed.
10 |
11 | * Download the [repo](https://github.com/hypery2k/galen_samples/archive/master.zip)
12 | * Unzip the folder
13 | * Open command prompt in extracted folder and go to the junit folder and run the tests:
14 | ```
15 | cd junit
16 | mvn verify
17 | ```
18 |
19 | ## Extend the sample
20 |
21 | * To extend the project, run the following command:
22 | ```
23 | cd junit
24 | mvn eclipse:eclipse idea:idea
25 | ```
26 | * Import the Junit project (junit-folder) in IDEA and Eclipse
27 |
--------------------------------------------------------------------------------
/javascript/README.MD:
--------------------------------------------------------------------------------
1 | # Galen samples for JavaScript
2 |
3 |
4 | ## Setup
5 |
6 | ```bash
7 | (sudo) npm install -g galenframework-cli
8 |
9 | ```
10 |
11 | ## Execution
12 |
13 | A showcase of JavaScript + Galen usage
14 |
15 | Jenkins Sample Build: [](https://martinreinhardt-online.de/jenkins/job/Galen/job/Galen_sample_JavaScript/)
16 |
17 | The sample script [runCI.sh](runCI.sh) just wrap up some calls for CI build within Jenkins:
18 |
19 | ```bash
20 | galen test . -DwebsiteUrl=${websiteUrl} --htmlreport ../../../reports/shopping-cart --testngreport ../../../reports/shopping-cart/testng.xml -Dwebdriver.chrome.driver=/opt/dev/chromedriver
21 |
22 | ```
23 | The following arguments are used:
24 |
25 | * -DwebsiteUrl - a url of page for Galen to test on (passed to test file)
26 | * -Dwebdriver.chrome.driver - path the ChromeDriver
27 | * --htmlreport - path to folder in which Galen should generate html reports
28 | * --testngreport - path to xml file in which Galen should write testng report
29 |
--------------------------------------------------------------------------------
/testng/src/test/java/sample/layout/CssLayoutTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package sample.layout;
5 |
6 | import java.util.Arrays;
7 |
8 | import org.openqa.selenium.By;
9 | import org.testng.annotations.Test;
10 |
11 | import util.testng.GalenBaseTest;
12 |
13 | /**
14 | * @author mreinhardt
15 | *
16 | */
17 | public class CssLayoutTest extends GalenBaseTest {
18 |
19 | public final static String NAV_FORM_BTN = "(//*[contains(@class,'bs-docs-sidenav')]/li/a)[6]";
20 |
21 | public final static String INPUT_EMAIL = "//*[contains(@data-example-id,'basic-forms')]//input[contains(@type,'email')]";
22 |
23 |
24 | @Test(dataProvider = "devices")
25 | public void shouldShowCorrectBaseLayout(final TestDevice device) throws Exception {
26 | // or use verifyPage("/css","/specs/cssPageLayout.gspec");
27 | load("/css/#forms");
28 | clickElement(By.xpath(NAV_FORM_BTN));
29 | enterText(By.xpath(INPUT_EMAIL),"invalidEmail");
30 | verifyPage(device,
31 | "/specs/cssPageLayout.gspec",
32 | Arrays.asList("Css", "Bootstrap"));
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/testng/src/test/java/sample/layout/GoogleLayoutTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package sample.layout;
5 |
6 |
7 | import java.util.Arrays;
8 |
9 | import org.openqa.selenium.By;
10 | import org.testng.annotations.Test;
11 |
12 | import util.testng.GalenBaseTest;
13 |
14 | /**
15 | * @author mreinhardt
16 | *
17 | */
18 | public class GoogleLayoutTest extends GalenBaseTest {
19 |
20 | public final static String NAV_FORM_BTN = "(//*[contains(@class,'bs-docs-sidenav')]/li/a)[6]";
21 |
22 | public final static String INPUT_EMAIL = "//*[contains(@data-example-id,'basic-forms')]//input[contains(@type,'email')]";
23 |
24 | protected String getDefaultURL(){
25 | return "https://google.com";
26 | }
27 |
28 | @Test(dataProvider = "devices")
29 | public void shouldShowCorrectBaseLayout(final TestDevice device) throws Exception {
30 | load("/");
31 | enterText(By.id("lst-ib"),"Galen Testing");
32 | clickElement(By.xpath("//*[contains(@class,'lsb')]//button"));
33 | verifyPage(device,
34 | "/specs/googlePageLayout.gspec",
35 | Arrays.asList("Google"));
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/junit/src/test/java/sample/layout/CssLayoutTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package sample.layout;
5 |
6 | import org.junit.Test;
7 | import org.openqa.selenium.By;
8 | import sample.util.GalenBaseTest;
9 |
10 | import java.util.Arrays;
11 |
12 | /**
13 | * @author mreinhardt
14 | */
15 | public class CssLayoutTest extends GalenBaseTest {
16 |
17 | public final static String NAV_FORM_BTN = "(//*[contains(@class,'bs-docs-sidenav')]/li/a)[6]";
18 |
19 | public final static String INPUT_EMAIL = "//*[contains(@data-example-id,'basic-forms')]//input[contains(@type,'email')]";
20 |
21 | /**
22 | * @param pTestDevice
23 | */
24 | public CssLayoutTest(TestDevice pTestDevice) {
25 | super(pTestDevice);
26 | }
27 |
28 | @Test
29 | public void shouldShowCorrectBaseLayout() throws Exception {
30 | // or use verifyPage("/css","/specs/cssPageLayout.gspec");
31 | load("/css/#forms");
32 | clickElement(By.xpath(NAV_FORM_BTN));
33 | enterText(By.xpath(INPUT_EMAIL), "invalidEmail");
34 | verifyPage("/specs/cssPageLayout.gspec", Arrays.asList("Css", "Bootstrap"));
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Martin Reinhardt
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/junit/src/test/java/sample/layout/GoogleLayoutTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package sample.layout;
5 |
6 | import org.junit.Test;
7 | import org.openqa.selenium.By;
8 | import sample.util.GalenBaseTest;
9 |
10 | import java.util.Arrays;
11 |
12 | /**
13 | * @author mreinhardt
14 | */
15 | public class GoogleLayoutTest extends GalenBaseTest {
16 |
17 | public final static String NAV_FORM_BTN = "(//*[contains(@class,'bs-docs-sidenav')]/li/a)[6]";
18 |
19 | public final static String INPUT_EMAIL = "//*[contains(@data-example-id,'basic-forms')]//input[contains(@type,'email')]";
20 |
21 | /**
22 | * @param pTestDevice
23 | */
24 | public GoogleLayoutTest(TestDevice pTestDevice) {
25 | super(pTestDevice);
26 | }
27 |
28 | protected String getDefaultURL() {
29 | return "https://google.com";
30 | }
31 |
32 | @Test
33 | public void shouldShowCorrectBaseLayout() throws Exception {
34 | load("/");
35 | enterText(By.id("lst-ib"), "Galen Testing");
36 | clickElement(By.xpath("//*[contains(@class,'lsb')]//button"));
37 | verifyPage("/specs/googlePageLayout.gspec", Arrays.asList("Google"));
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/javascript/testSuite/bootstrap/basic.test:
--------------------------------------------------------------------------------
1 | @@ table browsers
2 | | browerName | browser |
3 | | Chrome | chrome |
4 | | Firefox | firefox |
5 | @@ table devices
6 | | deviceName | tags | size |
7 | | Mobile | mobile | 320x600 |
8 | | Tablet | tablet | 640x480 |
9 | | Desktop | desktop | 1024x800 |
10 |
11 | @@ parameterized using browsers
12 | @@ parameterized using devices
13 | @@ groups home, page
14 | homepage on ${deviceName} in ${browerName} browser
15 | selenium ${browser} ${websiteUrl} ${size}
16 | check specs/homePageLayout.gspec --include "${device}"
17 |
18 | @@ parameterized using browsers
19 | @@ parameterized using devices
20 | @@ groups javascript, page
21 | javascript page on ${deviceName} in ${browerName} browser
22 | selenium ${browser} ${websiteUrl} ${size}
23 | check specs/homePageLayout.gspec --include "${device}"
24 | check specs/javascriptPageLayout.gspec --include "${device}"
25 |
26 | @@ parameterized using browsers
27 | @@ parameterized using devices
28 | @@ groups css, page
29 | css page on ${deviceName} in ${browerName} browser
30 | selenium ${browser} ${websiteUrl} ${size}
31 | check specs/cssPageLayout.gspec --include "${tags}"
--------------------------------------------------------------------------------
/javascript/testSuite/bootstrap/saucelabs.test:
--------------------------------------------------------------------------------
1 | @@ set
2 | sauceKey aff16b42-9c23-4cb6-adf7-38da9e02193a
3 | sauceUser galen_mreinhardt
4 | gridLogin ${sauceUser}:${sauceKey}
5 | gridUrl http://${gridLogin}@ondemand.saucelabs.com:80/wd/hub
6 | @@ table browsers
7 | | browserName | gridArgs |
8 | | Safari on Mac | --browser "safari" --version 8 --dc.platform "OS X 10.10" |
9 | | Opera | --browser "opera" --version 12 --dc.platform "Linux" |
10 | | Firefox | --browser "firefox" --version 34 --dc.platform "Linux" |
11 | | Chrome | --browser "chrome" --version 39 --dc.platform "Linux" |
12 | | IE 11 | --browser "internet explorer" --version 11 --dc.platform "Windows 8.1" |
13 | | Mobile Safari iOS 10.0 | --browser "Safari" --dc.deviceName "iPhone Simulator" --dc.deviceOrientation "portrait" --dc.platformName "iOS" --dc.platformVersion "10.2" --dc.appiumVersion "1.7.1" |
14 | | Mobile Chrome Android 6.0 | --browser "Chrome" --dc.deviceName "Android Emulator" --dc.deviceOrientation "portrait" --dc.platformName "Android" --dc.platformVersion "6.0" --dc.appiumVersion "1.7.1" |
15 | @@ parameterized using browsers
16 | Home page on ${browserName} browser
17 | selenium grid ${gridUrl} --page ${websiteUrl} ${gridArgs}
18 | check specs/homePageLayout.gspec --include "${device}"
19 |
--------------------------------------------------------------------------------
/junit/config:
--------------------------------------------------------------------------------
1 |
2 | # Range approximation
3 | # ~~~~~~~~~~~~~~~~~~~~~
4 | # Defines the approximation value for ranges when using "~" in galen page specs
5 | # This value means how many pixels or percents should it take constructing a range
6 | # e.g. if we define approximation as 5 then the following spec:
7 | # height: ~ 50 px
8 | # will actually be replaced by Galen with this:
9 | # height: 45 to 55px
10 | galen.range.approximation=3
11 |
12 |
13 | # Custom Listeners
14 | # ~~~~~~~~~~~~~~~~~~~~~~~
15 | # A comma separated list of class paths to reporting listeners
16 | # The defined listeners will be picked up by Galen and used for reporting
17 | #
18 | # galen.reporting.listeners=
19 |
20 |
21 | # Full screenshots
22 | # ~~~~~~~~~~~~~~~~~~~~
23 | # In some browsers it is not possible to create a complete screenshot of whole page.
24 | # With this property enabled Galen will scroll page and make screenshots of parts of it.
25 | # Then it will assemble it in a one big screenshot
26 | #
27 | galen.browser.screenshots.fullPage = true
28 |
29 |
30 |
31 | # Default browser
32 | # ~~~~~~~~~~~~~~~~~~~~~~~~
33 | # A browser that should be used by default in case it was not specified in galen test
34 | galen.default.browser=chrome
35 |
36 |
37 | # Color scheme spec precision
38 | # ~~~~~~~~~~~~~~~~~~~~~~~~
39 | # A value between 8 and 256 for color spectrum accuracy.
40 | spec.colorscheme.precision = 256
41 |
42 |
43 | # Using page urls from last checked page in HTML report
44 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
45 | # This property enables the use of last page url in a page test
46 | # Needed when for some pages on the website there is no way to open it by direct url
47 | # galen.reporting.html.useLastPageUrls = true
48 |
49 |
50 | # Color scheme spec test color range
51 | # ~~~~~~~~~~~~~~~~~~~~~~~~~
52 | # A value between 0 and 256 which defined the range of nearby colors
53 | # in spectrum which will be picked up for calculating the percentage of usage
54 | spec.colorscheme.testrange = 6
55 |
56 |
57 | # Running in Selenium Grid
58 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
59 | # You can run your tests in Selenium Grid without modifying the tests.
60 | # Just enable the "galen.browserFactory.selenium.runInGrid" property
61 | # and Galen will always choose a Selenium Grid instead of running tests against local browsers
62 | # Also make sure you provide the proper url to grid
63 | #
64 | galen.browserFactory.selenium.runInGrid = true
65 | galen.browserFactory.selenium.grid.url = http://localhost:4444/wd/hub
66 | galen.browserFactory.selenium.grid.browser = Firefox
67 | galen.browserFactory.selenium.grid.browserVersion = 16
68 | galen.browserFactory.selenium.grid.platform = XP
69 |
70 |
71 | # Exit with fail code in case of any failures
72 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
73 | galen.use.fail.exit.code = true
--------------------------------------------------------------------------------
/testng/config:
--------------------------------------------------------------------------------
1 |
2 | # Range approximation
3 | # ~~~~~~~~~~~~~~~~~~~~~
4 | # Defines the approximation value for ranges when using "~" in galen page specs
5 | # This value means how many pixels or percents should it take constructing a range
6 | # e.g. if we define approximation as 5 then the following spec:
7 | # height: ~ 50 px
8 | # will actually be replaced by Galen with this:
9 | # height: 45 to 55px
10 | galen.range.approximation=3
11 |
12 |
13 | # Custom Listeners
14 | # ~~~~~~~~~~~~~~~~~~~~~~~
15 | # A comma separated list of class paths to reporting listeners
16 | # The defined listeners will be picked up by Galen and used for reporting
17 | #
18 | # galen.reporting.listeners=
19 |
20 |
21 | # Full screenshots
22 | # ~~~~~~~~~~~~~~~~~~~~
23 | # In some browsers it is not possible to create a complete screenshot of whole page.
24 | # With this property enabled Galen will scroll page and make screenshots of parts of it.
25 | # Then it will assemble it in a one big screenshot
26 | #
27 | galen.browser.screenshots.fullPage = true
28 |
29 |
30 |
31 | # Default browser
32 | # ~~~~~~~~~~~~~~~~~~~~~~~~
33 | # A browser that should be used by default in case it was not specified in galen test
34 | galen.default.browser=firefox
35 |
36 |
37 | # Color scheme spec precision
38 | # ~~~~~~~~~~~~~~~~~~~~~~~~
39 | # A value between 8 and 256 for color spectrum accuracy.
40 | spec.colorscheme.precision = 256
41 |
42 |
43 | # Using page urls from last checked page in HTML report
44 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
45 | # This property enables the use of last page url in a page test
46 | # Needed when for some pages on the website there is no way to open it by direct url
47 | # galen.reporting.html.useLastPageUrls = true
48 |
49 |
50 | # Color scheme spec test color range
51 | # ~~~~~~~~~~~~~~~~~~~~~~~~~
52 | # A value between 0 and 256 which defined the range of nearby colors
53 | # in spectrum which will be picked up for calculating the percentage of usage
54 | spec.colorscheme.testrange = 6
55 |
56 |
57 | # Running in Selenium Grid
58 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
59 | # You can run your tests in Selenium Grid without modifying the tests.
60 | # Just enable the "galen.browserFactory.selenium.runInGrid" property
61 | # and Galen will always choose a Selenium Grid instead of running tests against local browsers
62 | # Also make sure you provide the proper url to grid
63 | #
64 | galen.browserFactory.selenium.runInGrid = true
65 | galen.browserFactory.selenium.grid.url = http://localhost:4444/wd/hub
66 | galen.browserFactory.selenium.grid.browser = Firefox
67 | galen.browserFactory.selenium.grid.browserVersion = 16
68 | galen.browserFactory.selenium.grid.platform = XP
69 |
70 |
71 | # Exit with fail code in case of any failures
72 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
73 | galen.use.fail.exit.code = true
--------------------------------------------------------------------------------
/javascript/gulp/test/basics.js:
--------------------------------------------------------------------------------
1 | /* globals describe, it, xit, before, after */
2 |
3 | var assert = require("assert");
4 | var gulp = require("gulp");
5 | var path = require("path");
6 | var es = require("event-stream");
7 | var util = require("util");
8 | var fs = require("fs");
9 | var rimraf = require("rimraf");
10 |
11 | var gulpGalen = require('../index.js');
12 |
13 | describe("gulp-galen", function () {
14 |
15 | describe("basic functionality", function () {
16 |
17 | this.timeout(100000);
18 |
19 | var options = {
20 | url: "https://www.google.com",
21 | size: "800x600",
22 | galenPath: path.resolve('node_modules', 'galenframework', 'bin', 'galen' + (process.platform === 'win32' ? '.cmd' : ''))
23 | };
24 |
25 | it("should iterate over some gspecs", function (done) {
26 | gulp.src("**/specs/google_success?.gspec").pipe(gulpGalen.check(options))
27 | .pipe(es.writeArray(function (err, arr) {
28 | assert(!err, "There where errors present");
29 | assert(arr, "Result missing");
30 | for (var i = 0; i < 2; i++) {
31 | assert(arr[i].path.match(/specs\/google_success.\.gspec$/),
32 | "File's path didn't end with specs/google_success?.gspec: '" + arr[i].path + "'");
33 | }
34 | done();
35 | }));
36 | });
37 |
38 | it("should handle failed specs", function (done) {
39 | try {
40 | expect(gulp.src("**/specs/google_failing.gspec").pipe(gulpGalen.check(options, function () {
41 | //ignore
42 | }))).toThrow(new Error("Unexpected error!"));
43 | done();
44 | } catch (e) {
45 | done();
46 | }
47 | });
48 |
49 | });
50 |
51 | describe("extended functionality", function () {
52 |
53 | this.timeout(30000);
54 |
55 | before(function (done) {
56 | rimraf("./tmp/test-reports", done);
57 | });
58 |
59 | xit("should support some variables based upon the current file", function (done) {
60 | gulp.src("**/specs/google1.gspec").pipe(gulpGalen.check({
61 | url: "https://www.google.com",
62 | size: "800x600",
63 | galenPath: "./node_modules/galenframework/bin/galen",
64 | testngreport: "./tmp/test-reports/testng-{basename}.xml"
65 | }, function (error) {
66 | es.writeArray(function (err, arr) {
67 | var fn = "./tmp/test-reports/testng-google_success1.gspec.xml";
68 | fs.stat(fn, function (err, stats) {
69 | assert(!err, "File not found: " + fn);
70 | assert(stats.isFile(), "Is no file: " + fn);
71 | });
72 | });
73 | done();
74 | }));
75 | });
76 |
77 | });
78 |
79 | });
--------------------------------------------------------------------------------
/javascript/node/test/basics.js:
--------------------------------------------------------------------------------
1 | /* globals describe, it, xit, before, after */
2 |
3 | var assert = require("assert");
4 | var gulp = require("gulp");
5 | var path = require("path");
6 | var es = require("event-stream");
7 | var util = require("util");
8 | var fs = require("fs");
9 | var rimraf = require("rimraf");
10 |
11 | var gulpGalen = require('../index.js');
12 |
13 | describe("gulp-galen", function () {
14 |
15 | describe("basic functionality", function () {
16 |
17 | this.timeout(100000);
18 |
19 | var options = {
20 | url: "https://www.google.com",
21 | size: "800x600",
22 | galenPath: path.resolve('node_modules', 'galenframework', 'bin', 'galen' + (process.platform === 'win32' ? '.cmd' : ''))
23 | };
24 |
25 | it("should iterate over some gspecs", function (done) {
26 | gulp.src("**/specs/google_success?.gspec").pipe(gulpGalen.check(options))
27 | .pipe(es.writeArray(function (err, arr) {
28 | assert(!err, "There where errors present");
29 | assert(arr, "Result missing");
30 | for (var i = 0; i < 2; i++) {
31 | assert(arr[i].path.match(/specs\/google_success.\.gspec$/),
32 | "File's path didn't end with specs/google_success?.gspec: '" + arr[i].path + "'");
33 | }
34 | done();
35 | }));
36 | });
37 |
38 | it("should handle failed specs", function (done) {
39 | try {
40 | expect(gulp.src("**/specs/google_failing.gspec").pipe(gulpGalen.check(options, function () {
41 | //ignore
42 | }))).toThrow(new Error("Unexpected error!"));
43 | done();
44 | } catch (e) {
45 | done();
46 | }
47 | });
48 |
49 | });
50 |
51 | describe("extended functionality", function () {
52 |
53 | this.timeout(30000);
54 |
55 | before(function (done) {
56 | rimraf("./tmp/test-reports", done);
57 | });
58 |
59 | xit("should support some variables based upon the current file", function (done) {
60 | gulp.src("**/specs/google1.gspec").pipe(gulpGalen.check({
61 | url: "https://www.google.com",
62 | size: "800x600",
63 | galenPath: "./node_modules/galenframework/bin/galen",
64 | testngreport: "./tmp/test-reports/testng-{basename}.xml"
65 | }, function (error) {
66 | es.writeArray(function (err, arr) {
67 | var fn = "./tmp/test-reports/testng-google_success1.gspec.xml";
68 | fs.stat(fn, function (err, stats) {
69 | assert(!err, "File not found: " + fn);
70 | assert(stats.isFile(), "Is no file: " + fn);
71 | });
72 | });
73 | done();
74 | }));
75 | });
76 |
77 | });
78 |
79 | });
--------------------------------------------------------------------------------
/javascript/testRunner/bootstrap/init.js:
--------------------------------------------------------------------------------
1 |
2 | var domain = "getbootstrap.com";
3 |
4 | var devices = {
5 | mobile: {
6 | deviceName: "mobile",
7 | size: "450x800",
8 | tags: ["mobile"]
9 | },
10 | tablet: {
11 | deviceName: "tablet",
12 | size: "600x800",
13 | tags: ["tablet"]
14 | },
15 | desktop: {
16 | deviceName: "desktop",
17 | size: "1100x800",
18 | tags: ["desktop"]
19 | }
20 | };
21 |
22 | var browsers = {
23 | chrome: {
24 | type: "chrome",
25 | browserName: "Chrome"
26 | },
27 | firefox: {
28 | type: "firefox",
29 | browserName: "Firefox"
30 | }
31 | };
32 |
33 | function openDriver(url, size, driver) {
34 | var driver = createDriver(null, size, driver);
35 |
36 | session.put("driver", driver);
37 |
38 | if (url != null) {
39 | if (url.indexOf("http://") != 0 && url.indexOf("https://") != 0) {
40 | url = "http://" + domain + url;
41 | }
42 | driver.get(url);
43 | }
44 | else {
45 | driver.get("http://" + domain);
46 | }
47 | return driver;
48 | }
49 |
50 |
51 | afterTest(function (test) {
52 | var driver = session.get("driver");
53 | if (driver != null) {
54 | if (test.isFailed()) {
55 | session.report().info("Screenshot").withAttachment("Screenshot", takeScreenshot(driver));
56 | }
57 | driver.quit();
58 | }
59 | });
60 |
61 | function _test(testNamePrefix, url, callback) {
62 | test(testNamePrefix + " on ${deviceName} device with firefox", function (device) {
63 | var driver = openDriver(url, device.size, "firefox");
64 | callback.call(this, driver, device);
65 | });
66 | }
67 |
68 | function _testWithBrowser(testNamePrefix, url, callback) {
69 | test(testNamePrefix + " on ${deviceName} device with ${browserName}", function (browser, device) {
70 | var driver = openDriver(url, device.size, browser.type);
71 | callback.call(this, driver, device, browser);
72 | });
73 | }
74 |
75 | function testOnAllDevicesAndBrowsers(testNamePrefix, url, callback) {
76 | forAll(browsers, function () {
77 | forAll(devices, function () {
78 | _testWithBrowser(testNamePrefix, url, callback);
79 | });
80 | });
81 | }
82 |
83 | function testOnDeviceAndBrowsers(device, testNamePrefix, url, callback) {
84 | forAll(browsers, function () {
85 | forOnly(device, function() {
86 | _testWithBrowser(testNamePrefix, url, callback);
87 | });
88 | });
89 | }
90 |
91 | function testOnAllDevices(testNamePrefix, url, callback) {
92 | forAll(devices, function () {
93 | _test(testNamePrefix, url, callback);
94 | });
95 | }
96 |
97 | function testOnDevice(device, testNamePrefix, url, callback) {
98 | forOnly(device, function() {
99 | _test(testNamePrefix, url, callback);
100 | });
101 | }
102 |
103 |
104 |
105 | /*
106 | Exporting functions to all other tests that will use this script
107 | */
108 | (function (export) {
109 | export.devices = devices;
110 | export.openDriver = openDriver;
111 | export.testOnAllDevices = testOnAllDevices;
112 | })(this);
113 |
--------------------------------------------------------------------------------
/javascript/grunt/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function (grunt) {
2 | require('load-grunt-tasks')(grunt);
3 |
4 | /*
5 | * Developer test suite. Uses the current (../tasks/galen.js) version
6 | * of the framework to launch the dynamic test example.
7 | *
8 | */
9 | var sauceUser = 'galen_mreinhardt';
10 | var sauceKey = 'aff16b42-9c23-4cb6-adf7-38da9e02193a';
11 | var package = grunt.file.readJSON('./package.json');
12 | var testPipeline = ['galen:local'];
13 | var BUILD_ID = package.version + '_' + String((new Date()).getTime());
14 | grunt.initConfig({
15 | galen: {
16 | options: {
17 | url: 'http://example.com/',
18 | output: true,
19 | concat: true
20 | },
21 | local: {
22 | src: ['test/**/*.js'],
23 | options: {
24 | devices: {
25 | desktop: {
26 | deviceName: 'desktop',
27 | browser: 'firefox',
28 | size: '1280x800'
29 | },
30 | tablet: {
31 | deviceName: 'tablet',
32 | browser: 'firefox',
33 | size: '768x576'
34 | }
35 | }
36 | }
37 | },
38 | sl: {
39 | src: ['test/**/*.js'],
40 | options: {
41 | seleniumGrid: {
42 | login: sauceUser,
43 | username: sauceUser,
44 | accessKey: sauceKey
45 | },
46 | devices: {
47 | desktop: {
48 | deviceName: 'desktop',
49 | browser: 'chrome',
50 | size: '1280x1024',
51 | desiredCapabilities: {
52 | name: 'example.com for desktop',
53 | platform: 'Windows 7',
54 | version: '43.0',
55 | passed: 'true',
56 | tags: [
57 | 'grunt galen',
58 | 'example.com',
59 | 'remote testing',
60 | 'desktop browser'
61 | ].join(','),
62 | build: BUILD_ID
63 | }
64 | },
65 | tablet: {
66 | deviceName: 'ipad',
67 | browser: 'ipad',
68 | desiredCapabilities: {
69 | name: 'example.com for tablet',
70 | 'device-orientation': 'portrait',
71 | platform: 'OS X 10.10',
72 | version: '8.0',
73 | passed: 'true',
74 | tags: [
75 | 'grunt galen',
76 | 'example.com',
77 | 'remote testing',
78 | 'ipad browser'
79 | ].join(','),
80 | build: BUILD_ID
81 | }
82 | },
83 | mobile: {
84 | deviceName: 'android',
85 | browser: 'android',
86 | desiredCapabilities: {
87 | name: 'example.com for mobile',
88 | 'device-orientation': 'portrait',
89 | platform: 'Linux',
90 | version: '4.4',
91 | passed: 'true',
92 | tags: [
93 | 'grunt galen',
94 | 'example.com',
95 | 'remote testing',
96 | 'android browser'
97 | ].join(','),
98 | build: BUILD_ID
99 | }
100 | }
101 | }
102 | }
103 | }
104 | }
105 | });
106 |
107 | grunt.registerTask('default', testPipeline);
108 | };
109 |
--------------------------------------------------------------------------------
/junit/src/test/resources/specs/shared/galen-extras-rules.js:
--------------------------------------------------------------------------------
1 |
2 | function _ruleRenderedInTable(rule, itemPattern, columns, verticalMargin, horizontalMargin) {
3 | var allItems = findAll(itemPattern);
4 |
5 | var currentColumn = 0;
6 |
7 | for (var i = 0; i < allItems.length - 1; i += 1) {
8 | if (currentColumn < columns - 1) {
9 | rule.addObjectSpecs(allItems[i].name, [
10 | "left-of " + allItems[i + 1].name + " " + horizontalMargin,
11 | "aligned horizontally all " + allItems[i + 1].name
12 | ]);
13 | }
14 |
15 | var j = i + columns;
16 |
17 | if (j < allItems.length) {
18 | rule.addObjectSpecs(allItems[i].name, [
19 | "above " + allItems[j].name + " " + verticalMargin,
20 | "aligned vertically all " + allItems[j].name
21 | ]);
22 | }
23 |
24 | currentColumn += 1;
25 | if (currentColumn === columns) {
26 | currentColumn = 0;
27 | }
28 | }
29 | }
30 |
31 | /**
32 | * This is a high-level spec for checking that elements are displayed in table layout
33 | * with different margins for vertical and horizontal sides
34 | * e.g.
35 | *
36 | * | menuItem-* are rendered in 2 column table layout, with 0 to 4px vertical and 1px horizontal margins
37 | */
38 | rule("%{itemPattern} are rendered in %{columns: [0-9]+} column table layout, with %{verticalMargin} vertical and %{horizontalMargin} horizontal margin", function (objectName, parameters) {
39 | _ruleRenderedInTable(this, parameters.itemPattern, parseInt(columns), parameters.verticalMargin, parameters.horizontalMargin);
40 | });
41 |
42 |
43 | /**
44 | * This is a high-level spec for checking that elements are displayed in table layout
45 | * e.g.
46 | *
47 | * | menuItem-* are rendered in 2 column table layout, with 0 to 4px margin
48 | */
49 | rule("%{itemPattern} are rendered in %{columns: [0-9]+} column table layout, with %{margin} margin", function (objectName, parameters) {
50 | _ruleRenderedInTable(this, parameters.itemPattern, parseInt(columns), parameters.margin, parameters.margin);
51 | });
52 |
53 |
54 | function _applyRuleBodyForAllElements(rule, objectPattern, appliesConditionCallback) {
55 | var allElements = findAll(parameters.objectPattern);
56 |
57 | if (allElements.length > 0) {
58 | for (var i = 0; i < allElements.length - 1; i += 1) {
59 | if (!appliesConditionCallback(allElements[i])) {
60 | return;
61 | }
62 | }
63 | rule.doRuleBody();
64 | }
65 | }
66 |
67 | function _applyRuleBodyForSingleElement(rule, objectPattern, appliesConditionCallback) {
68 | var allElements = findAll(parameters.objectPattern);
69 |
70 | if (allElements.length > 0) {
71 | for (var i = 0; i < allElements.length - 1; i += 1) {
72 | if (appliesConditionCallback(allElements[i])) {
73 | rule.doRuleBody();
74 | return;
75 | }
76 | }
77 | }
78 | }
79 |
80 | rule("if all %{objectPattern} are visible", function (objectName, parameters) {
81 | _applyRuleBodyForAllElements(this, parameters.objectPattern, function (element) {
82 | return element.isVisible();
83 | });
84 | });
85 |
86 |
87 | rule("if none of %{objectPattern} are visible", function (objectName, parameters) {
88 | _applyRuleBodyForAllElements(this, parameters.objectPattern, function (element) {
89 | return ! element.isVisible();
90 | });
91 | });
92 |
93 | rule("if any of %{objectPattern} is visible", function (objectName, parameters) {
94 | _applyRuleBodyForSingleElement(this, parameters.objectPattern, function (element) {
95 | return element.isVisible();
96 | });
97 | });
98 |
99 |
100 | rule("%{objectPattern} sides are inside %{containerObject} with %{margin} margin from %{sideAName} and %{sideBName}", function (objectName, parameters) {
101 | var items = findAll(parameters.objectPattern);
102 |
103 |
104 | if (items.length > 0) {
105 | this.addObjectSpecs(items[0].name, [ "inside " + parameters.containerObject + " " + parameters.margin + " " + parameters.sideAName ]);
106 |
107 | for (var i = 1; i < items.length - 1; i++) {
108 | this.addObjectSpecs(items[i].name, [ "inside " + parameters.containerObject ]);
109 | }
110 |
111 | this.addObjectSpecs(items[items.length - 1].name, [ "inside " + parameters.containerObject + " " + parameters.margin + " " + parameters.sideBName ]);
112 | } else {
113 | throw new Error("Couldn't find any items matching " + parameters.objectPattern);
114 | }
115 | });
116 |
117 |
--------------------------------------------------------------------------------
/testng/src/test/resources/specs/shared/galen-extras-rules.js:
--------------------------------------------------------------------------------
1 |
2 | function _ruleRenderedInTable(rule, itemPattern, columns, verticalMargin, horizontalMargin) {
3 | var allItems = findAll(itemPattern);
4 |
5 | var currentColumn = 0;
6 |
7 | for (var i = 0; i < allItems.length - 1; i += 1) {
8 | if (currentColumn < columns - 1) {
9 | rule.addObjectSpecs(allItems[i].name, [
10 | "left-of " + allItems[i + 1].name + " " + horizontalMargin,
11 | "aligned horizontally all " + allItems[i + 1].name
12 | ]);
13 | }
14 |
15 | var j = i + columns;
16 |
17 | if (j < allItems.length) {
18 | rule.addObjectSpecs(allItems[i].name, [
19 | "above " + allItems[j].name + " " + verticalMargin,
20 | "aligned vertically all " + allItems[j].name
21 | ]);
22 | }
23 |
24 | currentColumn += 1;
25 | if (currentColumn === columns) {
26 | currentColumn = 0;
27 | }
28 | }
29 | }
30 |
31 | /**
32 | * This is a high-level spec for checking that elements are displayed in table layout
33 | * with different margins for vertical and horizontal sides
34 | * e.g.
35 | *
36 | * | menuItem-* are rendered in 2 column table layout, with 0 to 4px vertical and 1px horizontal margins
37 | */
38 | rule("%{itemPattern} are rendered in %{columns: [0-9]+} column table layout, with %{verticalMargin} vertical and %{horizontalMargin} horizontal margin", function (objectName, parameters) {
39 | _ruleRenderedInTable(this, parameters.itemPattern, parseInt(columns), parameters.verticalMargin, parameters.horizontalMargin);
40 | });
41 |
42 |
43 | /**
44 | * This is a high-level spec for checking that elements are displayed in table layout
45 | * e.g.
46 | *
47 | * | menuItem-* are rendered in 2 column table layout, with 0 to 4px margin
48 | */
49 | rule("%{itemPattern} are rendered in %{columns: [0-9]+} column table layout, with %{margin} margin", function (objectName, parameters) {
50 | _ruleRenderedInTable(this, parameters.itemPattern, parseInt(columns), parameters.margin, parameters.margin);
51 | });
52 |
53 |
54 | function _applyRuleBodyForAllElements(rule, objectPattern, appliesConditionCallback) {
55 | var allElements = findAll(parameters.objectPattern);
56 |
57 | if (allElements.length > 0) {
58 | for (var i = 0; i < allElements.length - 1; i += 1) {
59 | if (!appliesConditionCallback(allElements[i])) {
60 | return;
61 | }
62 | }
63 | rule.doRuleBody();
64 | }
65 | }
66 |
67 | function _applyRuleBodyForSingleElement(rule, objectPattern, appliesConditionCallback) {
68 | var allElements = findAll(parameters.objectPattern);
69 |
70 | if (allElements.length > 0) {
71 | for (var i = 0; i < allElements.length - 1; i += 1) {
72 | if (appliesConditionCallback(allElements[i])) {
73 | rule.doRuleBody();
74 | return;
75 | }
76 | }
77 | }
78 | }
79 |
80 | rule("if all %{objectPattern} are visible", function (objectName, parameters) {
81 | _applyRuleBodyForAllElements(this, parameters.objectPattern, function (element) {
82 | return element.isVisible();
83 | });
84 | });
85 |
86 |
87 | rule("if none of %{objectPattern} are visible", function (objectName, parameters) {
88 | _applyRuleBodyForAllElements(this, parameters.objectPattern, function (element) {
89 | return ! element.isVisible();
90 | });
91 | });
92 |
93 | rule("if any of %{objectPattern} is visible", function (objectName, parameters) {
94 | _applyRuleBodyForSingleElement(this, parameters.objectPattern, function (element) {
95 | return element.isVisible();
96 | });
97 | });
98 |
99 |
100 | rule("%{objectPattern} sides are inside %{containerObject} with %{margin} margin from %{sideAName} and %{sideBName}", function (objectName, parameters) {
101 | var items = findAll(parameters.objectPattern);
102 |
103 |
104 | if (items.length > 0) {
105 | this.addObjectSpecs(items[0].name, [ "inside " + parameters.containerObject + " " + parameters.margin + " " + parameters.sideAName ]);
106 |
107 | for (var i = 1; i < items.length - 1; i++) {
108 | this.addObjectSpecs(items[i].name, [ "inside " + parameters.containerObject ]);
109 | }
110 |
111 | this.addObjectSpecs(items[items.length - 1].name, [ "inside " + parameters.containerObject + " " + parameters.margin + " " + parameters.sideBName ]);
112 | } else {
113 | throw new Error("Couldn't find any items matching " + parameters.objectPattern);
114 | }
115 | });
116 |
117 |
--------------------------------------------------------------------------------
/javascript/testRunner/bootstrap/specs/shared/galen-extras-rules.js:
--------------------------------------------------------------------------------
1 |
2 | function _ruleRenderedInTable(rule, itemPattern, columns, verticalMargin, horizontalMargin) {
3 | var allItems = findAll(itemPattern);
4 |
5 | var currentColumn = 0;
6 |
7 | for (var i = 0; i < allItems.length - 1; i += 1) {
8 | if (currentColumn < columns - 1) {
9 | rule.addObjectSpecs(allItems[i].name, [
10 | "left-of " + allItems[i + 1].name + " " + horizontalMargin,
11 | "aligned horizontally all " + allItems[i + 1].name
12 | ]);
13 | }
14 |
15 | var j = i + columns;
16 |
17 | if (j < allItems.length) {
18 | rule.addObjectSpecs(allItems[i].name, [
19 | "above " + allItems[j].name + " " + verticalMargin,
20 | "aligned vertically all " + allItems[j].name
21 | ]);
22 | }
23 |
24 | currentColumn += 1;
25 | if (currentColumn === columns) {
26 | currentColumn = 0;
27 | }
28 | }
29 | }
30 |
31 | /**
32 | * This is a high-level spec for checking that elements are displayed in table layout
33 | * with different margins for vertical and horizontal sides
34 | * e.g.
35 | *
36 | * | menuItem-* are rendered in 2 column table layout, with 0 to 4px vertical and 1px horizontal margins
37 | */
38 | rule("%{itemPattern} are rendered in %{columns: [0-9]+} column table layout, with %{verticalMargin} vertical and %{horizontalMargin} horizontal margin", function (objectName, parameters) {
39 | _ruleRenderedInTable(this, parameters.itemPattern, parseInt(columns), parameters.verticalMargin, parameters.horizontalMargin);
40 | });
41 |
42 |
43 | /**
44 | * This is a high-level spec for checking that elements are displayed in table layout
45 | * e.g.
46 | *
47 | * | menuItem-* are rendered in 2 column table layout, with 0 to 4px margin
48 | */
49 | rule("%{itemPattern} are rendered in %{columns: [0-9]+} column table layout, with %{margin} margin", function (objectName, parameters) {
50 | _ruleRenderedInTable(this, parameters.itemPattern, parseInt(columns), parameters.margin, parameters.margin);
51 | });
52 |
53 |
54 | function _applyRuleBodyForAllElements(rule, objectPattern, appliesConditionCallback) {
55 | var allElements = findAll(parameters.objectPattern);
56 |
57 | if (allElements.length > 0) {
58 | for (var i = 0; i < allElements.length - 1; i += 1) {
59 | if (!appliesConditionCallback(allElements[i])) {
60 | return;
61 | }
62 | }
63 | rule.doRuleBody();
64 | }
65 | }
66 |
67 | function _applyRuleBodyForSingleElement(rule, objectPattern, appliesConditionCallback) {
68 | var allElements = findAll(parameters.objectPattern);
69 |
70 | if (allElements.length > 0) {
71 | for (var i = 0; i < allElements.length - 1; i += 1) {
72 | if (appliesConditionCallback(allElements[i])) {
73 | rule.doRuleBody();
74 | return;
75 | }
76 | }
77 | }
78 | }
79 |
80 | rule("if all %{objectPattern} are visible", function (objectName, parameters) {
81 | _applyRuleBodyForAllElements(this, parameters.objectPattern, function (element) {
82 | return element.isVisible();
83 | });
84 | });
85 |
86 |
87 | rule("if none of %{objectPattern} are visible", function (objectName, parameters) {
88 | _applyRuleBodyForAllElements(this, parameters.objectPattern, function (element) {
89 | return ! element.isVisible();
90 | });
91 | });
92 |
93 | rule("if any of %{objectPattern} is visible", function (objectName, parameters) {
94 | _applyRuleBodyForSingleElement(this, parameters.objectPattern, function (element) {
95 | return element.isVisible();
96 | });
97 | });
98 |
99 |
100 | rule("%{objectPattern} sides are inside %{containerObject} with %{margin} margin from %{sideAName} and %{sideBName}", function (objectName, parameters) {
101 | var items = findAll(parameters.objectPattern);
102 |
103 |
104 | if (items.length > 0) {
105 | this.addObjectSpecs(items[0].name, [ "inside " + parameters.containerObject + " " + parameters.margin + " " + parameters.sideAName ]);
106 |
107 | for (var i = 1; i < items.length - 1; i++) {
108 | this.addObjectSpecs(items[i].name, [ "inside " + parameters.containerObject ]);
109 | }
110 |
111 | this.addObjectSpecs(items[items.length - 1].name, [ "inside " + parameters.containerObject + " " + parameters.margin + " " + parameters.sideBName ]);
112 | } else {
113 | throw new Error("Couldn't find any items matching " + parameters.objectPattern);
114 | }
115 | });
116 |
117 |
--------------------------------------------------------------------------------
/javascript/testSuite/bootstrap/specs/shared/galen-extras-rules.js:
--------------------------------------------------------------------------------
1 |
2 | function _ruleRenderedInTable(rule, itemPattern, columns, verticalMargin, horizontalMargin) {
3 | var allItems = findAll(itemPattern);
4 |
5 | var currentColumn = 0;
6 |
7 | for (var i = 0; i < allItems.length - 1; i += 1) {
8 | if (currentColumn < columns - 1) {
9 | rule.addObjectSpecs(allItems[i].name, [
10 | "left-of " + allItems[i + 1].name + " " + horizontalMargin,
11 | "aligned horizontally all " + allItems[i + 1].name
12 | ]);
13 | }
14 |
15 | var j = i + columns;
16 |
17 | if (j < allItems.length) {
18 | rule.addObjectSpecs(allItems[i].name, [
19 | "above " + allItems[j].name + " " + verticalMargin,
20 | "aligned vertically all " + allItems[j].name
21 | ]);
22 | }
23 |
24 | currentColumn += 1;
25 | if (currentColumn === columns) {
26 | currentColumn = 0;
27 | }
28 | }
29 | }
30 |
31 | /**
32 | * This is a high-level spec for checking that elements are displayed in table layout
33 | * with different margins for vertical and horizontal sides
34 | * e.g.
35 | *
36 | * | menuItem-* are rendered in 2 column table layout, with 0 to 4px vertical and 1px horizontal margins
37 | */
38 | rule("%{itemPattern} are rendered in %{columns: [0-9]+} column table layout, with %{verticalMargin} vertical and %{horizontalMargin} horizontal margin", function (objectName, parameters) {
39 | _ruleRenderedInTable(this, parameters.itemPattern, parseInt(columns), parameters.verticalMargin, parameters.horizontalMargin);
40 | });
41 |
42 |
43 | /**
44 | * This is a high-level spec for checking that elements are displayed in table layout
45 | * e.g.
46 | *
47 | * | menuItem-* are rendered in 2 column table layout, with 0 to 4px margin
48 | */
49 | rule("%{itemPattern} are rendered in %{columns: [0-9]+} column table layout, with %{margin} margin", function (objectName, parameters) {
50 | _ruleRenderedInTable(this, parameters.itemPattern, parseInt(columns), parameters.margin, parameters.margin);
51 | });
52 |
53 |
54 | function _applyRuleBodyForAllElements(rule, objectPattern, appliesConditionCallback) {
55 | var allElements = findAll(parameters.objectPattern);
56 |
57 | if (allElements.length > 0) {
58 | for (var i = 0; i < allElements.length - 1; i += 1) {
59 | if (!appliesConditionCallback(allElements[i])) {
60 | return;
61 | }
62 | }
63 | rule.doRuleBody();
64 | }
65 | }
66 |
67 | function _applyRuleBodyForSingleElement(rule, objectPattern, appliesConditionCallback) {
68 | var allElements = findAll(parameters.objectPattern);
69 |
70 | if (allElements.length > 0) {
71 | for (var i = 0; i < allElements.length - 1; i += 1) {
72 | if (appliesConditionCallback(allElements[i])) {
73 | rule.doRuleBody();
74 | return;
75 | }
76 | }
77 | }
78 | }
79 |
80 | rule("if all %{objectPattern} are visible", function (objectName, parameters) {
81 | _applyRuleBodyForAllElements(this, parameters.objectPattern, function (element) {
82 | return element.isVisible();
83 | });
84 | });
85 |
86 |
87 | rule("if none of %{objectPattern} are visible", function (objectName, parameters) {
88 | _applyRuleBodyForAllElements(this, parameters.objectPattern, function (element) {
89 | return ! element.isVisible();
90 | });
91 | });
92 |
93 | rule("if any of %{objectPattern} is visible", function (objectName, parameters) {
94 | _applyRuleBodyForSingleElement(this, parameters.objectPattern, function (element) {
95 | return element.isVisible();
96 | });
97 | });
98 |
99 |
100 | rule("%{objectPattern} sides are inside %{containerObject} with %{margin} margin from %{sideAName} and %{sideBName}", function (objectName, parameters) {
101 | var items = findAll(parameters.objectPattern);
102 |
103 |
104 | if (items.length > 0) {
105 | this.addObjectSpecs(items[0].name, [ "inside " + parameters.containerObject + " " + parameters.margin + " " + parameters.sideAName ]);
106 |
107 | for (var i = 1; i < items.length - 1; i++) {
108 | this.addObjectSpecs(items[i].name, [ "inside " + parameters.containerObject ]);
109 | }
110 |
111 | this.addObjectSpecs(items[items.length - 1].name, [ "inside " + parameters.containerObject + " " + parameters.margin + " " + parameters.sideBName ]);
112 | } else {
113 | throw new Error("Couldn't find any items matching " + parameters.objectPattern);
114 | }
115 | });
116 |
117 |
--------------------------------------------------------------------------------
/junit/src/test/java/sample/util/GalenBaseTest.java:
--------------------------------------------------------------------------------
1 | package sample.util;
2 |
3 | import com.galenframework.junit.GalenJUnitTestBase;
4 | import com.galenframework.gspeclang2.pagespec.SectionFilter;
5 | import org.apache.commons.lang3.StringUtils;
6 | import org.junit.runners.Parameterized.Parameters;
7 | import org.openqa.selenium.*;
8 | import org.openqa.selenium.firefox.FirefoxDriver;
9 | import org.openqa.selenium.remote.DesiredCapabilities;
10 | import org.openqa.selenium.remote.RemoteWebDriver;
11 |
12 | import java.net.MalformedURLException;
13 | import java.net.URL;
14 | import java.util.Arrays;
15 | import java.util.List;
16 | import java.util.Properties;
17 |
18 | import static java.util.Arrays.asList;
19 |
20 | /**
21 | * Base class for all Galen tests.
22 | *
23 | * To run with maven against Selenium grid use:
24 | * mvn verify -Dselenium.grid=http://grid-ip:4444/wd/hub
25 | */
26 | public abstract class GalenBaseTest extends GalenJUnitTestBase {
27 |
28 | private static final String ENV_URL = "http://getbootstrap.com";
29 |
30 | private TestDevice device;
31 |
32 | public GalenBaseTest(final TestDevice pTestDevice) {
33 | super();
34 | this.device = pTestDevice;
35 | }
36 |
37 | protected String getDefaultURL() {
38 | return ENV_URL;
39 | }
40 |
41 | public WebElement scrollToElement(final By selector) throws MalformedURLException {
42 | WebElement element = getDriver().findElement(selector);
43 | String coordY = Integer.toString(element.getLocation().getY());
44 | ((JavascriptExecutor) getDriver()).executeScript("window.scrollTo(0, " + coordY + ")");
45 | return element;
46 | }
47 |
48 | public void clickElement(final By selector) throws MalformedURLException {
49 | WebElement element = scrollToElement(selector);
50 | element.click();
51 | }
52 |
53 | public void enterText(final By selector, final String text) throws MalformedURLException {
54 | WebElement element = scrollToElement(selector);
55 | element.sendKeys(text);
56 | }
57 |
58 | public void verifyPage(final String uri, final String specPath, final List groups)
59 | throws Exception {
60 | load(uri,
61 | this.device.getScreenSize().getWidth(),
62 | this.device.getScreenSize().getHeight());
63 | checkLayout(specPath, new SectionFilter(device.getTags(), null),
64 | new Properties(), null);
65 | }
66 |
67 | public void verifyPage(final String specPath, final List groups)
68 | throws Exception {
69 | resize(this.device.getScreenSize().getWidth(), this.device.getScreenSize().getHeight());
70 | checkLayout(specPath, new SectionFilter(device.getTags(), null),
71 | new Properties(), null);
72 | }
73 |
74 | @Override
75 | public void load(final String uri) {
76 | // allow overwrite via parameters
77 | final String env = System.getProperty("selenium.start_uri");
78 | final String completeUrl = (StringUtils.isEmpty(env) ? getDefaultURL() : env) + uri;
79 | getDriver().get(completeUrl);
80 | }
81 |
82 | @Override
83 | public WebDriver createDriver() {
84 | final String grid = System.getProperty("selenium.grid");
85 | if (grid == null) {
86 | return new FirefoxDriver();
87 | } else {
88 | // chrome runs much faster in a selenium grid
89 | try {
90 | return new RemoteWebDriver(new URL(grid), DesiredCapabilities.chrome());
91 | } catch (MalformedURLException e) {
92 | throw new RuntimeException(e);
93 | }
94 | }
95 | }
96 |
97 | @Parameters
98 | public static Iterable