Skip to content
This repository has been archived by the owner on Sep 21, 2022. It is now read-only.

Commit

Permalink
Merge pull request #867 from gemini-testing/skip_in_notIn
Browse files Browse the repository at this point in the history
Add skip.in, skip.notIn, only.in and only.notIn methods to tests API
  • Loading branch information
Dmitriy-kiselyov authored Mar 20, 2018
2 parents 0b9e7bb + 7b1853a commit f2d029c
Show file tree
Hide file tree
Showing 10 changed files with 932 additions and 406 deletions.
113 changes: 69 additions & 44 deletions doc/tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,47 +71,6 @@ All methods are chainable:
(See `tolerance`option description in [config](./config.md) documentation
for details).

* `skip([browser])` — skip all tests and nested suites for:

- `skip()` — all browsers;

- `skip('id')` — browser with specified `id`;

- `skip('id', comment)` — browser with specified `id` and show `comment` in the report;

- `skip(/some RegExp/)` — browser with `id` which matches `/some RegExp/`;

- `skip(/some RegExp/, comment)` — browser with `id` which matches `/some RegExp/` and show `comment` in the report;

- `skip(['id1', /RegExp1/, ...])` — multiple browsers;

- `skip(['id1', /RegExp1/, ...], comment)` — multiple browsers and show `comment` in the report.

All browsers from subsequent calls to `.skip()` are added to the skip list:

```js
suite
.skip('id1')
.skip(/RegExp1/);
```

is equivalent to

```js
suite.skip([
'id1',
/RegExp1/
]);
```

* `browsers([browser])` — run all tests and nested suites in specified browsers:

- `browsers('id')` — browser with specified `id`;

- `browsers(/some RegExp/)` — browser `id` which matches `/some RegExp/`;

- `browsers(['id1', /RegExp1/, ...])` — multiple browsers.

* `capture(stateName, [options], callback(actions, find))` — defines a new
state to capture. Optional callback describes a sequence of actions to bring
the page to this state, starting from a **previous** state of the suite.
Expand Down Expand Up @@ -169,6 +128,72 @@ All methods are chainable:
* `after(callback(actions, find))` — use this function to execute some code
after the last state. The arguments of a callback are the same as for
`capture` and `before` callbacks and context is shared between all of them.

### Skip tests

Sometimes you need to skip tests in specific browsers. For example, tested features
are not available in some browsers yet.

* `skip.in([browser])` — skip all tests and nested suites for:

- `skip.in('id')` — browser with specified `id`;

- `skip.in('id', comment)` — browser with specified `id` and show `comment` in the report;

- `skip.in(/some RegExp/)` — browser with `id` which matches `/some RegExp/`;

- `skip.in(/some RegExp/, comment)` — browser with `id` which matches `/some RegExp/`
and show `comment` in the report;

- `skip.in(['id1', /RegExp1/, ...])` — multiple browsers;

- `skip.in(['id1', /RegExp1/, ...], comment)` — multiple browsers and show `comment` in the report.

To skip all tests in suite you can use `skip.in(/.*/)`.

All browsers from subsequent calls to `.skip.in` are added to the skip list:

```js
suite
.skip.in('id1')
.skip.in(/RegExp1/);
```

is equivalent to

```js
suite.skip.in([
'id1',
/RegExp1/
]);
```

* ~`skip([browser])`~_deprecated_.
Works the same way as `skip.in`, except to skip all tests you can also write `skip()`.

* `skip.notIn([browser])` — skip all tests and nested suites for all browsers,
except ones in the arguments. Accepts same arguments as `skip.in`.

To skip test silently, use `only.in` function. This way, skipped browsers will not appear in the report.

* `only.in([browser])` — run all tests and nested suites in specified browsers:

- `only.in('id')` — browser with specified `id`;

- `only.in(/some RegExp/)` — browser `id` which matches `/some RegExp/`;

- `only.in('id1', /RegExp1/, ...)` — multiple browsers, also accepts an array as argument.

* ~`browsers([browser])`~_deprecated_. Use `only.in` instead.

* `only.notIn([browser])` — run all tests and nested suites in all browsers, except
ones in the arguments. Accepts same arguments as `only.in`.

For example:
```js
suite.only.in(['chrome', 'firefox']);
suite.only.notIn(/ie/, 'opera');
```

## Nested suites

Expand All @@ -180,7 +205,7 @@ browser, even if URL was not changed.
```js
gemini.suite('parent', function(parent) {
parent.setUrl('/some/path')
.setCaptureElements('.selector1', '.selector2');
.setCaptureElements('.selector1', '.selector2')
.capture('state');

gemini.suite('first child', function(child) {
Expand All @@ -194,7 +219,7 @@ gemini.suite('parent', function(parent) {
child.setCaptureElements('.next-selector')
.capture('third state', function(actions, elements) {
// ...
})
});

gemini.suite('grandchild', function(grandchild) {
//child suites can have own childs
Expand All @@ -206,7 +231,7 @@ gemini.suite('parent', function(parent) {
gemini.suite('third child', function(child) {
//this suite uses completely different URL and set of elements
child.setUrl('/some/another/path')
.setCaptureElements('.different-selector');
.setCaptureElements('.different-selector')
.capture('fifth state');
});
});
Expand Down
18 changes: 2 additions & 16 deletions lib/suite.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module.exports = class Suite {
constructor(name) {
this.name = name;
this.url = null;
this.skipped = false;
this.skipped = [];
this.captureSelectors = null;
this.tolerance = null;
this.ignoreSelectors = [];
Expand Down Expand Up @@ -52,24 +52,10 @@ module.exports = class Suite {
}

skip(browserSkipMatcher) {
if (this.skipped === true) {
return;
}

if (!browserSkipMatcher) {
this.skipped = true;
} else {
this.skipped = _.isArray(this.skipped)
? this.skipped.concat(browserSkipMatcher)
: [browserSkipMatcher];
}
this.skipped = this.skipped.concat(browserSkipMatcher);
}

shouldSkip(browserId) {
if (_.isBoolean(this.skipped)) {
return this.skipped;
}

return this.skipped.some((browserSkipMatcher) => {
if (browserSkipMatcher.matches(browserId)) {
this.skipComment = browserSkipMatcher.comment;
Expand Down
42 changes: 42 additions & 0 deletions lib/tests-api/skip/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
'use strict';

const _ = require('lodash');

module.exports = class Skip {
constructor(suite) {
this._suite = suite;
}

_validateArgs(browsers) {
if (!this._isArrayOfStringsAndRegExps(browsers)) {
throw new TypeError('Browsers must be an array with strings and RegExp objects');
}
}

_shouldSkip(browsers, {negate} = {}) {
const fn = negate ? _.every : _.some;
return (browserId) => fn(this._mkBrowsersMatcher(browsers, {negate}), (matcher) => matcher(browserId));
}

_mkBrowsersMatcher(browsers, {negate}) {
const mkMatcher = (browser) => _.isRegExp(browser) ? browser.test.bind(browser) : _.isEqual.bind(null, browser);

return browsers.map((browser) => negate ? _.negate(mkMatcher(browser)) : mkMatcher(browser));
}

_isArrayOfStringsAndRegExps(arr) {
return _.isArray(arr) && _.every(arr, (item) => _.isString(item) || _.isRegExp(item));
}

in() {
return new Error('Not implemented');
}

notIn() {
return new Error('Not implemented');
}

buildAPI() {
return new Error('Not implemented');
}
};
59 changes: 59 additions & 0 deletions lib/tests-api/skip/only-builder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
'use strict';

const Skip = require('./index');
const _ = require('lodash');

module.exports = class OnlyBuilder extends Skip {
static create(suite) {
return new OnlyBuilder(suite);
}

constructor(suite) {
super(suite);
}

in(...browsers) {
return this._process(browsers);
}

notIn(...browsers) {
return this._process(browsers, {negate: true});
}

_process(browsers, opts = {negate: false}) {
browsers = normalizeArgs(browsers);
this._validateArgs(browsers);

this._suite.browsers = this._suite.browsers.filter(this._shouldSkip(browsers, opts));
return this;
}

buildAPI(context) {
const only = {
in: (...browsers) => {
this.in(...browsers);
return context;
},
notIn: (...browsers) => {
this.notIn(...browsers);
return context;
}
};
const browsers = (...browsers) => {
this.in(...browsers);
return context;
};

return {only, browsers};
}
};

function normalizeArgs(browsers) {
if (browsers.length === 0) {
return;
}
if (browsers.length === 1 && _.isArray(browsers[0])) {
return browsers[0];
}
return browsers;
}
52 changes: 52 additions & 0 deletions lib/tests-api/skip/skip-builder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
'use strict';

const Skip = require('./index');

module.exports = class SkipBuilder extends Skip {
static create(suite) {
return new SkipBuilder(suite);
}

constructor(suite) {
super(suite);
}

in(browsers, comment) {
return this._process(browsers, comment);
}

notIn(browsers, comment) {
return this._process(browsers, comment, {negate: true});
}

_process(browsers, comment, opts = {negate: false}) {
browsers = [].concat(browsers);
this._validateArgs(browsers);

this._suite.skip({matches: this._shouldSkip(browsers, opts), comment});
return this;
}

buildAPI(context) {
const skip = (browsers, comment) => {
if (!browsers) {
browsers = /.*/;
}

this.in(browsers, comment);
return context;
};

skip.in = (browsers, comment) => {
this.in(browsers, comment);
return context;
};

skip.notIn = (browsers, comment) => {
this.notIn(browsers, comment);
return context;
};

return {skip};
}
};
Loading

0 comments on commit f2d029c

Please sign in to comment.