Negatory. Postpone Mission.
    Share your code. npm Orgs help your team discover, share, and reuse code. Create a free org »

    jwebdriverpublic

    jWebDriver

    jWebDriver logo

    A webdriver client for Node.js

    Build Status NPM version License NPM count NPM count

    1. Official Site: http://jwebdriver.com/
    2. Language Switch: English, 简体中文, 繁體中文
    3. Change log: CHANGE
    4. API Doc: http://jwebdriver.com/api/
    5. Coverage: http://jwebdriver.com/coverage/ (81.26%)

    Features

    1. Support all webdriver protocols: https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol
    2. Support mobile native & webview by macaca: (https://macacajs.com/)
    3. Easy to use, support mix promise
    4. Support promise chain & generator & es7 await
    5. jQuery style test code, easy use for front engineer
    6. All test cover api
    7. Support hosts mode, different hosts for different test job
    8. Support with remote file upload
    9. Support chai work with promise mode

    Quick start

    1. Install Selenium server & browser driver.

      npm i selenium-standalone -g

      selenium-standalone install --drivers.firefox.baseURL=http://npm.taobao.org/mirrors/geckodriver --baseURL=http://npm.taobao.org/mirrors/selenium --drivers.chrome.baseURL=http://npm.taobao.org/mirrors/chromedriver --drivers.ie.baseURL=http://npm.taobao.org/mirrors/selenium

      selenium-standalone start

    2. Insall jWebDriver

      npm install jwebdriver

    3. Run test code

      node baidu.js

       var JWebDriver = require('jwebdriver');
      
       var driver = new JWebDriver();
      
       driver.session("chrome")
           .url('https://www.baidu.com/')
           .find('#kw')
           .val('mp3')
           .submit()
           .title()
           .then(function(title){
               console.log(title);
           })
           .close();
      

      mocha mocha-promise.js

       var JWebDriver = require('jwebdriver');
       var chai = require("chai");
       chai.should();
       chai.use(JWebDriver.chaiSupportChainPromise);
      
       describe('jWebDriver test', function(){
      
           this.timeout(30000);
      
           var browser;
           before(function(){
               var driver = new JWebDriver();
               return (browser = driver.session('chrome'));
           });
      
           it('should search baidu', function(){
               return browser.url('https://www.baidu.com/')
                   .find('#kw')
                   .should.have.length(1)
                   .val('mp3').submit()
                   .url()
                   .should.contain('wd=mp3');
           });
      
           after(function(){
               return browser.close();
           });
      
       });
      

      mocha mocha-generators.js

       var JWebDriver = require('jwebdriver');
       var chai = require("chai");
       chai.should();
       chai.use(JWebDriver.chaiSupportChainPromise);
      
       require('mocha-generators').install();
      
       describe('jWebDriver test', function(){
      
           var browser;
           before(function*(){
               var driver = new JWebDriver();
               browser = yield driver.session('chrome');
           });
      
           it('should search baidu', function*(){
               yield browser.url('https://www.baidu.com/');
               var kw = yield browser.find('#kw').should.have.length(1);
               yield kw.val('mp3').submit();
               yield browser.url().should.contain('wd=mp3');
           });
      
           after(function*(){
               yield browser.close();
           });
      
       });
      

      node macaca.js (for mobile native & webview)

       var path = require('path');
       var JWebDriver = require('jwebdriver');
      
       var driver = new JWebDriver({
           port: 3456
       });
      
       var appPath = '../test/resource/android.zip';
      
       driver.session({
               'platformName': 'android',
               'app': path.resolve(appPath)
           })
           .wait('//*[@resource-id="com.github.android_app_bootstrap:id/mobileNoEditText"]')
           .sendElementKeys('中文+Test+12345678')
           .wait('//*[@resource-id="com.github.android_app_bootstrap:id/codeEditText"]')
           .sendElementKeys('22222\n')
           .wait('name', 'Login')
           .click()
           .wait('name', 'list')
           .prop('text')
           .then(function(text){
               console.log(text)
           })
           .rect()
           .then(function(rect){
               console.log(rect)
           })
           .click()
           .sendActions('drag', {
               fromX: 200,
               fromY: 400,
               toX: 200,
               toY: 100,
               duration: 0.5
           })
           .sendActions('drag', {
               fromX: 100,
               fromY: 100,
               toX: 100,
               toY: 400,
               duration: 0.5
           })
           .wait('name', 'Gesture')
           .click()
           .back()
           .back()
           .wait('name', 'Baidu')
           .click()
           .webview()
           .wait('#index-kw')
           .sendKeys('mp3')
           .wait('#index-bn')
           .click()
           .url()
           .then(function(url){
               console.log(url);
           })
           .title()
           .then(function(title){
               console.log(title);
           })
           .native()
           .wait('name', 'PERSONAL')
           .click();
      

    More examples

    1. Baidu test
    2. Gooogle test
    3. Mocha Promise
    4. Mocha Generators
    5. Mobile test (Native&webview)
    6. Upload test
    7. Drag Drop test
    8. Co test
    9. ES7 async
    10. Plugin

    API Book

    jWebDriver have 3 Class: Driver, Broswer, Elements

    All api can used with chain promise and support generator & es7 async:

    browser.find('#kw').then(function(elements){
        return elements.val('test')
                       .submit();
    })
    .title()
    .then(function(title){
        console.log(title);
    });
    

    And you can use mix promise with Driver class, all method will copy to Driver from Broswer and Elements:

    var driver = new JWebDriver();
    
    driver.session("chrome")
        .url('https://www.baidu.com/')
        .find('#kw')
        .val('mp3')
        .submit()
        .title()
        .then(function(title){
            console.log(title);
        })
        .close();
    

    You can search all api here, include all mode of api:

    var co = require('co');
    
    co(function*(){
    
        // ========================== driver api ==========================
    
        var JWebDriver = require('jwebdriver');
    
        var driver = new JWebDriver(); // connect to http://127.0.0.1:4444
        var driver = new JWebDriver('127.0.0.1', '4444'); // connect to http://127.0.0.1:4444
        var driver = new JWebDriver({
            'host': '127.0.0.1',
            'port': 4444,
            'logLevel': 0, // 0: no log, 1: warning & error, 2: all log
            'nocolor': false,
            'speed': 100 // default: 0 ms
        });
        var wdInfo = yield driver.info(); // get webdriver server info
    
        // ========================== session api ==========================
    
        var arrSessions = yield driver.sessions(); // get all sessions
        for(var i=0;i<arrSessions.length;i++){
            yield arrSessions[i].close();
        }
        // new session
        var browser = yield driver.session('browser', '40.0', 'windows');
        var browser = yield driver.session({
            'browserName':'browser',
            'version': 'ANY',
            'platform': 'ANY'
        });
        // attach session
        var browser = yield driver.session({
            sessionId: 'xxxxxxxxxx'
        });
        // set manual proxy
        var browser = yield driver.session({
            'browserName':'browser',
            'proxy': {
                'proxyType': 'manual',
                'httpProxy': '192.168.1.1:1080',
                'sslProxy': '192.168.1.1:1080'
            }
        });
        // set pac proxy
        var browser = yield driver.session({
            'browserName':'browser',
            'proxy': {
                'proxyType': 'pac',
                'proxyAutoconfigUrl': 'http://x.x.x.x/test.pac'
            }
        });
        // set hosts
        var browser = yield driver.session({
            'browserName':'browser',
            'hosts': '192.168.1.1 www.alibaba.com\r\n192.168.1.1 www.google.com'
        });
        // attach session
        var browser = yield driver.session('xxxxxxxxxx'); // session id
    
        // get session info
        var capabilities = yield browser.info(); // get capabilities
        var isSupported = yield browser.support('javascript'); // get capability supported: javascript, cssselector, screenshot, storage, alert, database, rotatable
        yield browser.config({
            pageloadTimeout: 5000, // page onload timeout
            scriptTimeout: 1000, // sync script timeout
            asyncScriptTimeout: 1000, // async script timeout
            implicitTimeout: 1000 // implicit timeout
        });
        yield browser.close(); // close session
        yield browser.sleep(1000); // sleep
    
        // get webdriver log
        var logTypes = yield browser.logTypes();
        var logs = yield browser.logs('browser');
    
        // ========================== window ==========================
    
        var curWindowHandle = yield browser.windowHandle(); // get current window handle
        var arrWindowHandles = yield browser.windowHandles(); // get all windows
        yield browser.switchWindow('handleid'); // focus to window
        yield browser.switchWindow(0); // focus to first window
        yield browser.switchWindow(1); // focus to second window
        var newWindowHandle = yield browser.newWindow('http://www.alibaba.com/', 'testwindow', 'width=200,height=200'); // open new window and return windowHandle
        yield browser.closeWindow(); // close current window
    
        // ========================== frame ==========================
    
        var elements = yield browser.frames(); // get all frames
        yield browser.switchFrame(0); // focus to frame 0
        yield browser.switchFrame(1); // focus to frame 1
        yield browser.switchFrame('#iframe_id'); // focus to frame #iframe_id
        yield browser.switchFrame(null); // focus to main page
        yield browser.switchFrameParent(); // focus to parent context
    
        // ========================== position & size & maximize & screenshot ==========================
    
        var position = yield browser.position(); // return {x: 1, y: 1}
        yield browser.position(10, 10); // set position
        yield browser.position({
            x: 10,
            y: 10
        });
        var info = yield browser.size(); // return {width: 100, height: 100}
        yield browser.size(100, 100); // set size
        yield browser.size({
            width: 100,
            height: 100
        });
        yield browser.maximize();
        var png_base64  = yield browser.getScreenshot();// get the screen shot, base64 type
        var png_base64  = yield browser.getScreenshot('d:/test.png');// get the screen shot, and save to file
        var png_base64 = yield browser.getScreenshot({
            elem: '#id'
        }); // get the element shot, (require install gm)
        var png_base64 = yield browser.getScreenshot({
            elem: '#id',
            filename: 'test.png'
        }); // get the element shot, and save to file
    
        // ========================== url & title & source ==========================
    
        yield browser.url('http://www.alibaba.com/'); // goto url
        var url = yield browser.url(); // get url
        var title = yield browser.title(); // get title
        var source = yield browser.source(); // get source code
        var html = yield browser.html(); // get html code, nick name of source
    
        // ========================== navigator ==========================
    
        yield browser.refresh(); // refresh page
        yield browser.back(); // back to previous page
        yield browser.forward(); // forward to next page
    
        yield browser.scrollTo('#id'); // scroll to element (first element)
        yield browser.scrollTo('#id', 10, 10); // scroll to element (first element)
        yield browser.scrollTo('#id', { // scroll to element (first element)
            x: 10,
            y: 10
        });
        yield browser.scrollTo(10, 10);
        yield browser.scrollTo({
            x: 10,
            y: 10
        });
        var elements = yield browser.find('#divtest');
        elements.scrollTo(0, 100); // scroll all elements to x, y
    
        // ========================== cookie ==========================
    
        var value = yield browser.cookie('test'); // get cookie
        yield browser.cookie('test', '123'); // set cookie
        yield browser.cookie('test', '123', { // https://code.google.com/p/selenium/wiki/JsonWireProtocol#Cookie_JSON_Object
            path: '',
            domain: '',
            secure: '',
            httpOnly: '',
            expiry: ''
        });
        yield browser.cookie('test',123, {
            expiry: '7 day' // second|minute|hour|day|month|year
        });
        yield browser.removeCookie('test'); // delete cookie
        var mapCookies = yield browser.cookies(); // get all cookie
        yield browser.clearCookies(); // delete all cookies
    
        // ========================== local storage && session storage ==========================
    
        var arrKeys = yield browser.localStorageKeys(); // get all local storage keys
        var value = yield browser.localStorage('test'); // get local storage value
        yield browser.localStorage('test', '1'); // set local storage value
        yield browser.removeLocalStorage('test'); // delete local storage
        yield browser.clearLocalStorages(); // clear all local sotrage
    
        var arrKeys = yield browser.sessionStorageKeys(); // get all session storage keys
        var value = yield browser.sessionStorage('test'); // get session storage value
        yield browser.sessionStorage('test', '1'); // set session storage value
        yield browser.removeSessionStorage('test'); // delete session storage
        yield browser.clearSessionStorages(); // clear all session sotrage
    
        // ========================== alert, confirm, prompt ==========================
    
        var msg = yield browser.getAlert();// get alert text
        if(msg !== null){
            yield browser.setAlert('test');// set msg to prompt
            yield browser.acceptAlert(); // accept alert
            yield browser.dismissAlert(); // dismiss alert
        }
    
        // ========================== mouse ==========================
    
        var MouseButtons = browser.MouseButtons;
        yield browser.mouseMove(element); // move to center of element
        yield browser.mouseMove('#id'); // move to center of element
        yield browser.mouseMove('#id', 10, 10); // move to offset of the element
        yield browser.mouseMove('#id', {x: 10, y: 10}); // move to offset of the element
        yield browser.mouseDown(); // left mouse button down
        yield browser.mouseDown(MouseButtons.RIGHT); // right mouse button down
        yield browser.mouseDown('RIGHT'); // right mouse button down
        yield browser.mouseUp(); // left mouse button up
        yield browser.mouseUp(MouseButtons.RIGHT); // right mouse button up
        yield browser.mouseUp('RIGHT'); // right mouse button up
        yield browser.click();
        yield browser.click(MouseButtons.RIGHT);
        yield browser.click('RIGHT');
        yield browser.dblClick();
        yield browser.dragDrop('#a', '#b'); // drag a drop to b
        yield browser.dragDrop({
            selector: '#a',
            x: 1,
            y: 1
        }, {
            selector: '#b',
            x: 2,
            y: 2
        });
    
        // ========================== keyboard ==========================
    
        yield browser.sendKeys('abc');
        var Keys = browser.Keys;
        yield browser.keyDown(Keys.CTRL);
        yield browser.keyDown('CTRL');
        yield browser.sendKeys('a'+Keys.LEFT);
        yield browser.keyUp(Keys.CTRL);
        yield browser.keyUp('CTRL');
        yield browser.sendKeys('{CTRL}a{CTRL}');
    
        // ========================== eval ==========================
    
        // sync eval
        var title = yield browser.eval(function(){
            return document.title;
        });
        var value = yield browser.eval(function(arg1, arg2){
            return arg1;
        }, 1, 2);
        var value = yield browser.eval(function(arg1, arg2){
            return arg1;
        }, [1, 2]);
        // async eval
        var value = yield browser.eval(function(arg1, arg2, done){
            setTimeout(function(){
                done(arg2);
            }, 2000);
        }, 1, 2);
        // pass element to eval
        var tagName = yield browser.eval(function(elements){
            return elements[0].tagName;
        }, yield browser.find('#id'));
    
        // ========================== element ==========================
    
        var elements = yield browser.wait('#id');// wait for element
        if(elements.length === 1){
            console.log('#id displayed');
        }
        yield elements.sleep(300); // sleep ms
        var elements = yield browser.wait('#id', 5000);// wait for element, 5000 ms timeout
        var elements = yield browser.wait('#id', {
            timeout: 10000, // set timeout, default: 10000
            displayed: true, // wait for element displayed, default: true
            removed: false // wait for element removed, default: false
        });
        var elements = yield browser.wait('name', 'aaa', 5000); // support type: class name|css selector|id|name|link text|partial link text|tag name|xpath
    
        var elements = yield browser.find('#id'); // find element
        var elements = yield browser.findVisible('span'); // find visible element
        var elements = yield browser.find('active');// get active element
        var elements = yield browser.find('#id');// get element by css selector
        var elements = yield browser.find('//html/body');// get element by xpath
        var elements = yield browser.find('name', 'aaa'); // support type: class name|css selector|id|name|link text|partial link text|tag name|xpath
        var elements = yield elements.find('.class'); // find all child element
        var isEqual = yield elements.equal('#bbb a'); // test if two elements refer to the same DOM element.
    
        // elements filter with sync mode
        var elements = yield elements.get(0); // get element by index
        var elements = yield elements.first(); // get first element
        var elements = yield elements.last(); // get last element
        var elements = yield elements.slice(1, 2); // get element from start to end
    
        // elements filter for chain promise
        elements.get(0, true).click(); // get element by index
        elements.first(0, true).click(); // get first element
        elements.last(0, true).click(); // get last element
        elements.slice(1, 2, true).click(); // get element from start to end
    
        // traversal the elements
        for(var i=0;i<elements.length;i++){
            var element = yield elements.get(i);
            console.log(yield element.text());
        }
    
        var tagName = yield element.tagName(); // get tagname (first element)
        var value = element.val(); // equal to element.attr('value');
        yield element.val('mp3'); // equal to: element.clear().sendKeys('mp3');
        var value = yield element.attr('id'); // get attribute value (first element)
        var value = yield element.prop('id'); // get property value (first element)
        var info = yield element.rect(); // get rect info (first element)
        var value = yield element.css('border'); // get css value (first element)
        yield element.clear(); // clear input & textarea value
        var text = yield element.text(); // get displayed text (first element)
    
        var offset = yield element.offset(); // get offset from left top corner of the page (first element)
        var offset = yield element.offset(true); // get offset from left top corner of the screen (first element)
        var size = yield element.size(); // return {width: 100, height: 100} (first element)
        var isDisplayed = yield element.displayed(); // determine if an element is currently displayed (first element)
        var isEnabled = yield element.enabled(); //is element enabled (first element)
        var isSelected = yield element.selected(); // is element selected (first element)
    
        // select option
        yield element.select(0); // select index
        yield element.select('book'); // select value
        yield element.select({
            type: 'value', // index | value | text
            value: 'book'
        });
    
        yield element.sendKeys('abc'); // send keys to element
        var Keys = browser.Keys;
        yield element.sendKeys('a'+Keys.LEFT);
        yield element.sendKeys('{CTRL}a{CTRL}');
    
        yield element.click(); // click element
        yield element.dblClick(); // dblClick element
        yield element.dragDropTo('#id'); // dragDrop to element (first element)
        yield element.dragDropTo('#id', 10, 10); // dragDrop to element (first element)
        yield element.dragDropTo({
            selector: '#id',
            x: 10,
            y: 10
        }); // dragDrop to element (first element)
    
        var fileElement = browser.wait('#file');
        yield fileElement.uploadFile('c:/test.jpg');// upload file to browser machine and set temp path to <input type="file">
        yield element.submit();// submit form
    
        // ========================== mobile api ==========================
        // touch down, touch move, touch up
        yield browser.touchDown(10, 10);
        yield browser.touchDown({
            x: 10, // X coordinate on the screen.
            y: 10  // Y coordinate on the screen.
        });
        yield browser.touchMove(10, 10);
        yield browser.touchMove({
            x: 10, // X coordinate on the screen.
            y: 10  // Y coordinate on the screen.
        });
        yield browser.touchUp(10, 10);
        yield browser.touchUp({
            x: 10, // X coordinate on the screen.
            y: 10  // Y coordinate on the screen.
        });
        // scroll
        yield browser.touchScroll(10, 10); // Use this command if you don't care where the scroll starts on the screen
        yield browser.touchScroll({
            x: 10, // The x offset in pixels to scrollby.
            y: 10  // The y offset in pixels to scrollby.
        });
        // flick
        yield browser.touchFlick({ // Use this flick command if you don't care where the flick starts on the screen.
            xspeed: 5, // The x speed in pixels per second.
            yspeed: 0  // The y speed in pixels per second.
        });
    
        // element api
        var element = yield browser.find('#id');
        yield element.touchClick();
        yield element.touchDblClick();
        yield element.touchLongClick();
        yield element.touchScroll(10, 10);
        yield element.touchScroll({
            x: 10, // The x offset in pixels to scroll by.
            y: 10  // The y offset in pixels to scroll by.
        });
        yield element.touchFlick(10, 10, 5); // flick to x: 10, y: 10 with speed 5
        yield element.touchFlick({
            x: 10, // The x offset in pixels to flick by.
            y: 10, // The y offset in pixels to flick by.
            speed: 5 // The speed in pixels per seconds
        });
    
        var orientation = yield browser.orientation(); // return LANDSCAPE|PORTRAIT
        yield browser.orientation('LANDSCAPE'); // set orientation: LANDSCAPE|PORTRAIT
    
        // ========================== geo location ==========================
    
        var loc = yield browser.geolocation(); // return {latitude: number, longitude: number, altitude: number}
        yield browser.geolocation(1, 1, 1); // set location
        yield browser.geolocation({
            latitude: 1,
            longitude: 1,
            altitude: 1
        });
    
        // ========================== macaca api ==========================
    
        var arrContexts = yield browser.contexts(); // get all contexts
        var contextId = yield browser.context(); // get context id
        yield browser.context('NATIVE_APP'); // set context id
        yield browser.native(); // set context to native
        yield browser.webview(); // set context to webview
    
        // tap
        yield browser.sendActions('tap', { x: 100, y: 100});
        yield element.sendActions('tap');
    
        // doubleTap
        yield browser.sendActions('doubleTap', { x: 100, y: 100});
        yield element.sendActions('doubleTap');
    
        // press
        yield browser.sendActions('press', { x: 100, y: 100});
        yield element.sendActions('press', { duration: 2 });
    
        // pinch
        yield element.sendActions('pinch', { scale: 2 }); // ios
        yield element.sendActions('pinch', { direction: "in", percent: 50 }); // android
    
        // rotate
        yield element.sendActions('rotate', { rotation: 6, velocity: 1 });
    
        // drag
        yield driver.sendActions('drag', { fromX: 100, fromY: 100, toX: 200, toY: 200 });
        yield element.sendActions('drag', { toX: 200, toY: 200 })
    
    }).then(function(){
        console.log('All done!')
    }).catch(function(error){
        console.log(error);
    });
    

    How to get element screen shot?

    1. Install gm

      brew install graphicsmagick (Mac)

      sudo apt-get install graphicsmagick (Linux)

      http://www.graphicsmagick.org/download.html (Windows)

    2. Get shot

      var png_base64 = yield browser.getScreenshot({ elem: '#id', filename: 'test.png' });

    How to extend method to driver?

    var JWebDriver = require('jwebdriver');
    
    var driver = new JWebDriver();
    
    JWebDriver.addMethod('searchMp3', function(){
        return this.find('#kw').val('mp3').submit();
    });
    
    driver.session("chrome")
        .url('https://www.baidu.com/')
        .searchMp3()
        .title()
        .then(function(title){
            console.log(title);
        })
        .close();
    

    License

    jWebDriver is released under the MIT license:

    The MIT License

    Copyright (c) 2014-2017 Yanis Wang yanis.wang@gmail.com

    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    Thanks

    install

    npm i jwebdriver

    Downloadslast 7 days

    81

    version

    2.2.5

    license

    MIT

    repository

    github.com

    last publish

    collaborators

    • avatar