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

Commit

Permalink
Merge v0.9.7 changes into mainline
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergey Tatarintsev committed Feb 9, 2015
2 parents 3f15a2f + 8ac32be commit 35dda90
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 6 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Expand Up @@ -6,6 +6,13 @@
Use `suite.ignoreElements(selector1, selector2, ...)` to specify
the selectors to ignore (@SevInf).

## 0.9.7 - 2015-02-09

* Add new wait methods (@SevInf):
- `waitForElementToShow`
- `waitForElementToHide`
- `waitForJSCondition`

## 0.9.6 - 2015-01-27

* Work on a pages that modify `Array.prototype` (@SevInf).
Expand Down
10 changes: 9 additions & 1 deletion doc/tests.md
Expand Up @@ -205,7 +205,15 @@ actions.executeJS(function(window) {

* `wait(milliseconds)` – wait for specified amount of time before next action. If it is the last action in
sequence, delay the screenshot for this amount of time.
* `sendKeys([element], keys)` – send a series of keyboard strokes to the specified element or
* `waitForElementToShow(selector, [timeout])` - waits unitl element, matched by `selector` will become visible.
Fails if element does not appear after `timeout` milliseconds (1000 by default).
* `waitForElementToHide(selector, [timeout])` - waits until element, matched by `selector` will become invisible
or will be completely removed from DOM. Fails if element still visible after `timeout`
milliseconds (1000 by default).
* `waitForJSCondition(function(window), timeout)` - waits until specified function return `true`. Function will be
executed in browser context, so any references to outer scope won't work. Fails if after `timeout` milliseconds
function still returns `false` (1000 by default).
* `sendKeys([element], keys)` - send a series of keyboard strokes to the specified element or
currently active element on a page.

You can send a special key using one of the provided constants, i.e:
Expand Down
9 changes: 8 additions & 1 deletion doc/tests.ru.md
Expand Up @@ -175,6 +175,13 @@
**NB**: Функция выполняется в контексте браузера, поэтому любые ссылки на её внешний контекст работать не будут.

* `wait(milliseconds)` – ожидание указанного времени до выполнения следующего действия. Если действие является последним в списке, откладывает снятие скриншота на этот период времени.
* `waitForElementToShow(selector, [timeout])` - ждет пока на странице появится элемент, попадающий под `selector`.
Завершается с ошибкой, если по истечении `timeout` миллисекунд элемент так и не появился (по умолчанию 1000).
* `waitForElementToHide(selector, [timeout])` - ждет пока элемент, попадающий под `selector`, пропадет со страницы.
Завершается с ошибкой, если по истечении `timeout` миллисекунд элемент все еще отображается (по умолчанию 1000).
* `waitForJSCondition(function(window), timeout)` - ждет пока указанная функция вернет `true`. Функция выполняется
в контексте браузера, поэтому ссылки на объекты из внешней области видимости работать не будут. Завершается с
ошибкой, если по истечении `timeout` миллисекунд функция все еще возвращает `false` (по умолчанию 1000).
* `sendKeys([element], keys)` – отправляет серию нажатий на клавиатуру к указанному или к активному в данный момент элементу страницы.
Вы можете отправить специальную клавишу, используя одну из предусмотренных констант, а именно:

Expand All @@ -194,4 +201,4 @@
в локальной системе (там же, где запущен `gemini`).
* `focus(element)` – устанавливает фокус на указанный элемент.
* `setWindowSize(width, height)` – устанавливает размера окна браузера.
* `tap(element)` - делает тап по элементу на устройстве с тач интерфейсом.
* `tap(element)` - делает тап по элементу на устройстве с тач интерфейсом.
66 changes: 63 additions & 3 deletions lib/browser/actions.js
Expand Up @@ -3,6 +3,7 @@
var q = require('q'),
fs = require('q-io/fs'),
inherit = require('inherit'),
wd = require('wd'),
promiseUtil = require('../promise-util'),
suiteUtil = require('../suite-util'),
StateError = require('../errors/state-error'),
Expand Down Expand Up @@ -35,6 +36,10 @@ function replaceStack(error, stack) {
error.stack = [message].concat(stack.split('\n').slice(1)).join('\n');
}

function serializeFunc(func) {
return '(' + func.toString() + '(window));';
}

module.exports = inherit({

__constructor: function(browser) {
Expand All @@ -51,6 +56,62 @@ module.exports = inherit({
return this;
},

waitForElementToShow: function waitForElementToShow(selector, timeout) {
this._waitElementAction(this.waitForElementToShow, selector, {
timeout: timeout,
asserter: wd.asserters.isDisplayed,
error: 'was not shown'
});

return this;
},

waitForElementToHide: function waitForElementToHide(selector, timeout) {
this._waitElementAction(this.waitForElementToHide, selector, {
timeout: timeout,
asserter: wd.asserters.isNotDisplayed,
error: 'was not hidden'
});

return this;
},

_waitElementAction: function(method, selector, options) {
if (typeof selector !== 'string') {
throw new TypeError(method.name + ' accepts only CSS selectors');
}

var timeout = ('timeout' in options? options.timeout : 1000);

var _this = this;
this._pushAction(method, function() {
return _this._driver.waitForElementByCssSelector(selector, options.asserter, timeout)
.fail(function() {
//assuming its timeout error, no way to distinguish
return q.reject(new StateError(
'Element ' + selector + ' ' + options.error + ' in ' + timeout + 'ms'));
});
});

return this;
},

waitForJSCondition: function(jsFunc, timeout) {
if (typeof jsFunc !== 'function') {
throw new TypeError('waitForCondition should accept function');
}
timeout = (typeof timeout === 'undefined'? 1000 : timeout);

var _this = this;
this._pushAction(this.waitForJSCondition, function() {
return _this._driver.waitFor(wd.asserters.jsCondition(serializeFunc(jsFunc)), timeout)
.fail(function() {
return q.reject(new StateError('Condition was not met in ' + timeout + 'ms'));
});
});
return this;
},

_pushAction: function(method, action) {
var stackHolder = {};

Expand Down Expand Up @@ -286,10 +347,9 @@ module.exports = inherit({
throw new TypeError('executeJS argument should be function');
}

var _this = this,
code = '(' + callback.toString() + '(window));';
var _this = this;
this._pushAction(this.executeJS, function executeJS() {
return _this._driver.execute(code);
return _this._driver.execute(serializeFunc(callback));
});
return this;
},
Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "gemini",
"version": "0.9.6",
"version": "0.9.7",
"description": "UI Screenshot testing utility",
"bin": {
"gemini": "./bin/gemini"
Expand Down

0 comments on commit 35dda90

Please sign in to comment.