# jWebDriver **Repository Path**: tinglab/jWebDriver ## Basic Information - **Project Name**: jWebDriver - **Description**: A webdriver client for Node.js - **Primary Language**: JavaScript - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-08-16 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README jWebDriver ================ ![jWebDriver logo](https://raw.github.com/yaniswang/jWebDriver/master/logo.png) 一个NodeJs平台下的WebDriver客户端 [![Build Status](https://img.shields.io/travis/yaniswang/jWebDriver.svg)](https://travis-ci.org/yaniswang/jWebDriver) [![NPM version](https://img.shields.io/npm/v/jwebdriver.svg?style=flat)](https://www.npmjs.com/package/jwebdriver) [![License](https://img.shields.io/npm/l/jwebdriver.svg?style=flat)](https://www.npmjs.com/package/jwebdriver) [![NPM count](https://img.shields.io/npm/dm/jwebdriver.svg?style=flat)](https://www.npmjs.com/package/jwebdriver) [![NPM count](https://img.shields.io/npm/dt/jwebdriver.svg?style=flat)](https://www.npmjs.com/package/jwebdriver) 1. 官方网站: [http://jwebdriver.com/](http://jwebdriver.com/) 2. 语言切换: [English](https://github.com/yaniswang/jWebDriver/blob/master/README.md), [简体中文](https://github.com/yaniswang/jWebDriver/blob/master/README_zh-cn.md), [繁體中文](https://github.com/yaniswang/jWebDriver/blob/master/README_zh-tw.md) 3. 更新日志: [CHANGE](https://github.com/yaniswang/jWebDriver/blob/master/CHANGE.md) 4. API文档: [http://jwebdriver.com/api/](http://jwebdriver.com/api/) 5. 覆盖率: [http://jwebdriver.com/coverage/](http://jwebdriver.com/coverage/) (81.26%) 6. 钉钉交流群:11779932(加入验证:jWebDriver),下载钉钉:[https://www.dingtalk.com/](https://www.dingtalk.com/) 功能 ================ 1. 支持所有WebDriver协议API: [https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol](https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol) 2. 支持无线Native和Webview,基于macaca实现: ([https://macacajs.com/](https://macacajs.com/)) 3. 简单易用,支持混合式Promise 4. 支持链式Promise & generator & es7 await 5. jQuery风格的测试代码, 对前端开发人员简单易懂 6. 全单元测试覆盖 7. 支持hosts模式, 不同测试任务使用不同的hosts绑定 8. 支持远程文件上传,以支持grid方式执行机集群 9. 支持链式chai断言 快速开始 ================ 1. 安装 Selenium server 和驱动. > 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. 安装 jWebDriver > npm install jwebdriver 3. 运行测试脚本 > 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(); 更多示例 ================ 1. [Baidu test](https://github.com/yaniswang/jWebDriver/blob/master/example/baidu.js) 2. [Gooogle test](https://github.com/yaniswang/jWebDriver/blob/master/example/google.js) 3. [Mocha Promise](https://github.com/yaniswang/jWebDriver/blob/master/example/mocha-promise.js) 4. [Mocha Generators](https://github.com/yaniswang/jWebDriver/blob/master/example/mocha-generators.js) 5. [Mobile test (Native&webview)](https://github.com/yaniswang/jWebDriver/blob/master/example/macaca.js) 6. [Upload test](https://github.com/yaniswang/jWebDriver/blob/master/example/upload.js) 7. [Drag Drop test](https://github.com/yaniswang/jWebDriver/blob/master/example/dragdrop.js) 8. [Co test](https://github.com/yaniswang/jWebDriver/blob/master/example/co.js) 9. [ES7 async](https://github.com/yaniswang/jWebDriver/blob/master/example/es7async.js) 10. [Plugin](https://github.com/yaniswang/jWebDriver/blob/master/example/plugin.js) API手册 ================ jWebDriver 有3个类: Driver, Broswer, Elements 所有API均支持 链式Promise 和 generator,以及es7 async语法: ------------------------------------------ browser.find('#kw').then(function(elements){ return elements.val('test') .submit(); }) .title() .then(function(title){ console.log(title); }); 并且,你也可以基于Driver类使用混合链式Promise, 所有API方法都会从Browser和Elements类复制到Driver类的实例上: ------------------------------------------ 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(); 你可以下面搜索所有的API,已经包括了所有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 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); }); 如何获取元素的截图? ------------------------------------------ 1. 安装gm组件 > `brew install graphicsmagick` (Mac) > `sudo apt-get install graphicsmagick` (Linux) > [http://www.graphicsmagick.org/download.html](http://www.graphicsmagick.org/download.html) (Windows) 2. 获取截图 var png_base64 = yield browser.getScreenshot({ elem: '#id', filename: 'test.png' }); 如何扩展自定义方法? ------------------------------------------ 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(); 协议 ================ jWebDriver 基于 MIT 协议发布: > The MIT License > > Copyright (c) 2014-2017 Yanis Wang > > 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. 感谢 ================ * Selenium: [http://code.google.com/p/selenium/](http://code.google.com/p/selenium/) * xtend: [https://npmjs.org/package/xtend](https://npmjs.org/package/xtend) * mocha: [https://npmjs.org/package/mocha](https://npmjs.org/package/mocha) * chai: [https://github.com/chaijs/chai](https://github.com/chaijs/chai) * istanbul: [https://github.com/gotwarlost/istanbul](https://github.com/gotwarlost/istanbul) * Grunt: [http://gruntjs.com/](http://gruntjs.com/) * JSHint: [https://github.com/jshint/jshint](https://github.com/jshint/jshint) * node-zip: [https://github.com/daraosn/node-zip](https://github.com/daraosn/node-zip) * Express: [https://github.com/strongloop/express](https://github.com/strongloop/express) * request: [https://github.com/request/request](https://github.com/request/request) * co: [https://github.com/tj/co](https://github.com/tj/co) * PhantomJs: [https://github.com/Medium/phantomjs](https://github.com/Medium/phantomjs) * GraphicsMagick: [http://www.graphicsmagick.org/](http://www.graphicsmagick.org/) * GitHub: [https://github.com/](https://github.com/)