Skip to content

jnutter/node-wd-sync

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

252 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

wd-sync

NOTE: API change in 1.0.0, see section below.

A synchronous version with a nice api of wd, the lightweight WebDriver / Selenium2 client for node.js, built using node-fibers.

Remote testing with Sauce Labs also works.

install

npm install wd-sync

code samples

CoffeeScript

# assumes that selenium server is running

wdSync = require 'wd-sync'
  
# 1/ simple Wd example 

{browser, sync} = wdSync.remote()

sync ->        
  console.log "server status:", @status()
  console.log "session id:", @getSessionId()
  @init browserName:'firefox'
  console.log "session capabilities:", @sessionCapabilities()

  @get "http://google.com"
  console.log @title()          

  queryField = @elementByName 'q'
  @type queryField, "Hello World"  
  @type queryField, "\n"

  @setWaitTimeout 3000      
  @elementByCss '#ires' # waiting for new page to load
  console.log @title()

  console.log @elementByNameIfExists 'not_exists' # undefined

  @quit()  

JavaScript

// assumes that selenium server is running

var wdSync = require('wd-sync');

// 1/ simple Wd example 

var client = wdSync.remote()
    , browser = client.browser
    , sync = client.sync;

sync( function() {
  
  console.log("server status:", browser.status());
  console.log("session id:", browser.getSessionId());
  browser.init( { browserName: 'firefox'} );
  console.log("session capabilities:", browser.sessionCapabilities());
  
  browser.get("http://google.com");
  console.log(browser.title());
  
  var queryField = browser.elementByName('q');
  browser.type(queryField, "Hello World");
  browser.type(queryField, "\n");
  
  browser.setWaitTimeout(3000);
  browser.elementByCss('#ires'); // waiting for new page to load
  console.log(browser.title());
  
  console.log(browser.elementByNameIfExists('not_exists')); // undefined
  
  browser.quit();

});

doc

Doc and README modifications must be done in the doc/template directory, then run 'cake doc:build'.

examples

supported methods

JsonWireProtocol wd
GET /status
Query the server's current status.
status() -> status
POST /session
Create a new session.
init(desired) -> sessionID
Initialize the browser.
GET /sessions
Returns a list of the currently active sessions.

sessions() -> sessions

## Alternate strategy to get session capabilities from server session list
altSessionCapabilities() -> capabilities

GET /session/:sessionId
Retrieve the capabilities of the specified session.
sessionCapabilities() -> capabilities
DELETE /session/:sessionId
Delete the session.
quit()
Destroy the browser.
POST /session/:sessionId/timeouts
Configure the amount of time that a particular type of operation can execute for before they are aborted and a |Timeout| error is returned to the client.
setPageLoadTimeout(ms)
(use setImplicitWaitTimeout and setAsyncScriptTimeout to set the other timeouts)
POST /session/:sessionId/timeouts/async_script
Set the amount of time, in milliseconds, that asynchronous scripts executed by /session/:sessionId/execute_async are permitted to run before they are aborted and a |Timeout| error is returned to the client.
setAsyncScriptTimeout(ms)
POST /session/:sessionId/timeouts/implicit_wait
Set the amount of time the driver should wait when searching for elements.
setImplicitWaitTimeout(ms)
GET /session/:sessionId/window_handle
Retrieve the current window handle.
windowHandle() -> handle
GET /session/:sessionId/window_handles
Retrieve the list of all window handles available to the session.
windowHandles() -> arrayOfHandles
GET /session/:sessionId/url
Retrieve the URL of the current page.
url() -> url
POST /session/:sessionId/url
Navigate to a new URL.
get(url)
Get a new url.
POST /session/:sessionId/forward
Navigate forwards in the browser history, if possible.
forward()
POST /session/:sessionId/back
Navigate backwards in the browser history, if possible.
back()
POST /session/:sessionId/refresh
Refresh the current page.
refresh()
POST /session/:sessionId/execute
Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame.

execute(code, args) -> result
execute(code) -> result
args: script argument array (optional)

Execute script using eval(code):
safeExecute(code, args) -> result
safeExecute(code) -> result
args: script argument array (optional)

Evaluate expression (using execute):
eval(code) -> value

Evaluate expression (using safeExecute):
safeEval(code) -> value

POST /session/:sessionId/execute_async
Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame.

executeAsync(code, args) -> result
executeAsync(code) -> result
args: script argument array (optional)

Execute async script using eval(code):
safeExecuteAsync(code, args) -> result
safeExecuteAsync(code) -> result
args: script argument array (optional)

GET /session/:sessionId/screenshot
Take a screenshot of the current page.
takeScreenshot() -> screenshot
POST /session/:sessionId/frame
Change focus to another frame on the page.
frame(frameRef)
POST /session/:sessionId/window
Change focus to another window.
window(name)
DELETE /session/:sessionId/window
Close the current window.
close()
POST /session/:sessionId/window/:windowHandle/size
Change the size of the specified window.

windowSize(handle, width, height)

setWindowSize(width, height, handle)
setWindowSize(width, height)
width: width in pixels to set size to
height: height in pixels to set size to
handle: window handle to set size for (optional, default: 'current')

GET /session/:sessionId/window/:windowHandle/size
Get the size of the specified window.
getWindowSize(handle) -> size
getWindowSize() -> size
handle: window handle to get size (optional, default: 'current')
POST /session/:sessionId/window/:windowHandle/position
Change the position of the specified window.
setWindowPosition(x, y, handle)
setWindowPosition(x, y)
x: the x-coordinate in pixels to set the window position
y: the y-coordinate in pixels to set the window position
handle: window handle to set position for (optional, default: 'current')
GET /session/:sessionId/window/:windowHandle/position
Get the position of the specified window.
getWindowPosition(handle) -> position
getWindowPosition() -> position
handle: window handle to get position (optional, default: 'current')
POST /session/:sessionId/window/:windowHandle/maximize
Maximize the specified window if not already maximized.
maximize(handle)
GET /session/:sessionId/cookie
Retrieve all cookies visible to the current page.
allCookies() -> cookies
POST /session/:sessionId/cookie
Set a cookie.
setCookie(cookie)
cookie example:
{name:'fruit', value:'apple'}
## Optional cookie fields
path, domain, secure, expiry
DELETE /session/:sessionId/cookie
Delete all cookies visible to the current page.
deleteAllCookies()
DELETE /session/:sessionId/cookie/:name
Delete the cookie with the given name.
deleteCookie(name)
GET /session/:sessionId/source
Get the current page source.
source() -> source
GET /session/:sessionId/title
Get the current page title.
title() -> title
POST /session/:sessionId/element
Search for an element on the page, starting from the document root.

element(using, value) -> element

elementByClassName(value) -> element
elementByCssSelector(value) -> element
elementById(value) -> element
elementByName(value) -> element
elementByLinkText(value) -> element
elementByPartialLinkText(value) -> element
elementByTagName(value) -> element
elementByXPath(value) -> element
elementByCss(value) -> element

POST /session/:sessionId/elements
Search for multiple elements on the page, starting from the document root.

elements(using, value) -> elements

elementsByClassName(value) -> elements
elementsByCssSelector(value) -> elements
elementsById(value) -> elements
elementsByName(value) -> elements
elementsByLinkText(value) -> elements
elementsByPartialLinkText(value) -> elements
elementsByTagName(value) -> elements
elementsByXPath(value) -> elements
elementsByCss(value) -> elements

## Retrieve an element avoiding not found exception and returning null instead
elementOrNull(using, value) -> element

elementByClassNameOrNull(value) -> element
elementByCssSelectorOrNull(value) -> element
elementByIdOrNull(value) -> element
elementByNameOrNull(value) -> element
elementByLinkTextOrNull(value) -> element
elementByPartialLinkTextOrNull(value) -> element
elementByTagNameOrNull(value) -> element
elementByXPathOrNull(value) -> element
elementByCssOrNull(value) -> element

## Retrieve an element avoiding not found exception and returning undefined instead
elementIfExists(using, value) -> element

elementByClassNameIfExists(value) -> element
elementByCssSelectorIfExists(value) -> element
elementByIdIfExists(value) -> element
elementByNameIfExists(value) -> element
elementByLinkTextIfExists(value) -> element
elementByPartialLinkTextIfExists(value) -> element
elementByTagNameIfExists(value) -> element
elementByXPathIfExists(value) -> element
elementByCssIfExists(value) -> element

## Check if element exists
hasElement(using, value) -> boolean

hasElementByClassName(value) -> boolean
hasElementByCssSelector(value) -> boolean
hasElementById(value) -> boolean
hasElementByName(value) -> boolean
hasElementByLinkText(value) -> boolean
hasElementByPartialLinkText(value) -> boolean
hasElementByTagName(value) -> boolean
hasElementByXPath(value) -> boolean
hasElementByCss(value) -> boolean

POST /session/:sessionId/element/active
Get the element on the page that currently has focus.
active() -> element
POST /session/:sessionId/element/:id/element
Search for an element on the page, starting from the identified element.

element.element(using, value) -> element

element.elementByClassName(value) -> element
element.elementByCssSelector(value) -> element
element.elementById(value) -> element
element.elementByName(value) -> element
element.elementByLinkText(value) -> element
element.elementByPartialLinkText(value) -> element
element.elementByTagName(value) -> element
element.elementByXPath(value) -> element
element.elementByCss(value) -> element

POST /session/:sessionId/element/:id/elements
Search for multiple elements on the page, starting from the identified element.

element.elements(using, value) -> elements

element.elementsByClassName(value) -> elements
element.elementsByCssSelector(value) -> elements
element.elementsById(value) -> elements
element.elementsByName(value) -> elements
element.elementsByLinkText(value) -> elements
element.elementsByPartialLinkText(value) -> elements
element.elementsByTagName(value) -> elements
element.elementsByXPath(value) -> elements
element.elementsByCss(value) -> elements

POST /session/:sessionId/element/:id/click
Click on an element.

clickElement(element)

element.click()

POST /session/:sessionId/element/:id/submit
Submit a FORM element.
submit(element)
Submit a `FORM` element.
GET /session/:sessionId/element/:id/text
Returns the visible text for the element.

text(element) -> text
element: specific element, 'body', or undefined

element.text() -> text

## Check if text is present
textPresent(searchText, element) -> boolean
element: specific element, 'body', or undefined

element.textPresent(searchText) -> boolean

POST /session/:sessionId/element/:id/value
Send a sequence of key strokes to an element.

type(element, keys)
Type keys (all keys are up at the end of command).
special key map: wd.SPECIAL_KEYS (see lib/special-keys.js)

element.type(keys)

POST /session/:sessionId/keys
Send a sequence of key strokes to the active element.
keys(keys)
Press keys (keys may still be down at the end of command).
special key map: wd.SPECIAL_KEYS (see lib/special-keys.js)
GET /session/:sessionId/element/:id/name
Query for an element's tag name.

getTagName(element) -> name

element.getTagName() -> name

POST /session/:sessionId/element/:id/clear
Clear a TEXTAREA or text INPUT element's value.

clear(element)

element.clear()

GET /session/:sessionId/element/:id/selected
Determine if an OPTION element, or an INPUT element of type checkbox or radiobutton is currently selected.

isSelected(element) -> selected

element.isSelected() -> selected

GET /session/:sessionId/element/:id/enabled
Determine if an element is currently enabled.

isEnabled(element) -> enabled

element.isEnabled() -> enabled

GET /session/:sessionId/element/:id/attribute/:name
Get the value of an element's attribute.

getAttribute(element, attrName) -> value

element.getAttribute(attrName) -> value

Get element value (in value attribute):
getValue(element) -> value

element.getValue() -> value

GET /session/:sessionId/element/:id/equals/:other
Test if two element IDs refer to the same DOM element.

element.equals(other) -> value

equalsElement(element, other ) -> value

GET /session/:sessionId/element/:id/displayed
Determine if an element is currently displayed.

isDisplayed(element) -> displayed

element.isDisplayed() -> displayed

GET /session/:sessionId/element/:id/location
Determine an element's location on the page.

getLocation(element) -> location

element.getLocation() -> location

GET /session/:sessionId/element/:id/size
Determine an element's size in pixels.

getSize(element) -> size

element.getSize() -> size

GET /session/:sessionId/element/:id/css/:propertyName
Query the value of an element's computed CSS property.

getComputedCss(element, cssProperty ) -> value

element.getComputedCss(cssProperty ) -> value

element.getComputedCss(cssProperty ) -> value

GET /session/:sessionId/orientation
Get the current browser orientation.
getOrientation() -> orientation
POST /session/:sessionId/orientation
Set the browser orientation.
setOrientation() -> orientation
GET /session/:sessionId/alert_text
Gets the text of the currently displayed JavaScript alert(), confirm(), or prompt() dialog.
alertText() -> text
POST /session/:sessionId/alert_text
Sends keystrokes to a JavaScript prompt() dialog.
alertKeys(keys)
POST /session/:sessionId/accept_alert
Accepts the currently displayed alert dialog.
acceptAlert()
POST /session/:sessionId/dismiss_alert
Dismisses the currently displayed alert dialog.
dismissAlert()
POST /session/:sessionId/moveto
Move the mouse by an offset of the specificed element.
moveTo(element, xoffset, yoffset)
Move to element, xoffset and y offset are optional.
POST /session/:sessionId/click
Click any mouse button (at the coordinates set by the last moveto command).
click(button)
Click on current element.
Buttons: {left: 0, middle: 1 , right: 2}
POST /session/:sessionId/buttondown
Click and hold the left mouse button (at the coordinates set by the last moveto command).
buttonDown()
POST /session/:sessionId/buttonup
Releases the mouse button previously held (where the mouse is currently at).
buttonUp()
POST /session/:sessionId/doubleclick
Double-clicks at the current mouse coordinates (set by moveto).
doubleclick()
POST /session/:sessionId/touch/flick
Flick on the touch screen using finger motion events.

flick(xSpeed, ySpeed, swipe)
Flicks, starting anywhere on the screen.
flick(element, xoffset, yoffset, speed)
Flicks, starting at element center.

element.flick(xoffset, yoffset, speed)

POST /session/:sessionId/local_storage
Set the storage item for the given key.
setLocalStorageKey(key, value)
# uses safeExecute() due to localStorage bug in Selenium
DELETE /session/:sessionId/local_storage
Clear the storage.
clearLocalStorage()
# uses safeExecute() due to localStorage bug in Selenium
GET /session/:sessionId/local_storage/key/:key
Get the storage item for the given key.
getLocalStorageKey(key)
# uses safeEval() due to localStorage bug in Selenium
DELETE /session/:sessionId/local_storage/key/:key
Remove the storage item for the given key.
removeLocalStorageKey(key)
# uses safeExecute() due to localStorage bug in Selenium
EXTRA Opens a new window (using Javascript window.open):
newWindow(url, name)
newWindow(url)
name: optional window name
Window can later be accessed by name with the window method,
or by getting the last handle returned by the windowHandles method.
EXTRA windowName() -> name
EXTRA waitForElement(using, value, timeout)
EXTRA waitForVisible(using, value, timeout)
EXTRA waitForElementByClassName(value, timeout)
waitForElementByCssSelector(value, timeout)
waitForElementById(value, timeout)
waitForElementByName(value, timeout)
waitForElementByLinkText(value, timeout)
waitForElementByPartialLinkText(value, timeout)
waitForElementByTagName(value, timeout)
waitForElementByXPath(value, timeout)
waitForElementByCss(value, timeout)
EXTRA waitForVisibleByClassName(value, timeout)
waitForVisibleByCssSelector(value, timeout)
waitForVisibleById(value, timeout)
waitForVisibleByName(value, timeout)
waitForVisibleByLinkText(value, timeout)
waitForVisibleByPartialLinkText(value, timeout)
waitForVisibleByTagName(value, timeout)
waitForVisibleByXPath(value, timeout)
waitForVisibleByCss(value, timeout)
EXTRA isVisible(element ) -> boolean
isVisible(queryType, querySelector) -> boolean
EXTRA Retrieves the pageIndex element (added for Appium):
getPageIndex(element) -> pageIndex
EXTRA Waits for JavaScript condition to be true (polling within wd client):
waitForCondition(conditionExpr, timeout, pollFreq) -> boolean
waitForCondition(conditionExpr, timeout) -> boolean
waitForCondition(conditionExpr) -> boolean
conditionExpr: condition expression, should return a boolean
timeout: timeout (optional, default: 1000)
pollFreq: pooling frequency (optional, default: 100)
return true if condition satisfied, error otherwise.
EXTRA Waits for JavaScript condition to be true (async script polling within browser):
waitForConditionInBrowser(conditionExpr, timeout, pollFreq) -> boolean
waitForConditionInBrowser(conditionExpr, timeout) -> boolean
waitForConditionInBrowser(conditionExpr) -> boolean
conditionExpr: condition expression, should return a boolean
timeout: timeout (optional, default: 1000)
pollFreq: pooling frequency (optional, default: 100)
return true if condition satisfied, error otherwise.
EXTRA isVisible() -> boolean

available environments

WebDriver

local WebDriver / Selenium2 server

Sauce Labs

Remote testing with Sauce Labs.

Headless

Headless testing using Zombie.

notes regarding headless/zombie:

  • only worth using for simple pages, not relying heavily on Javacripts.
  • the headless functionality wont be maintained/improved, at least until Zombie 2 is stable.

tests

local / selenium server:

1/ starts the selenium server with chromedriver:

java -jar selenium-server-standalone-2.25.0.jar -Dwebdriver.chrome.driver=<PATH>/chromedriver

2a/ run tests

cake test:local 

2b/ run clean test (making sure wd-zombie is not installed first)

cake test

remote / Sauce Labs

1/ follow the instructions here to configure your username and access key.

2/ run tests

cake test:sauce

headless

once:

cake test:prepare:headless

then:

cake test:headless

About

sync version of wd

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published