Git Product home page Git Product logo

webdriver.dart's Introduction

CI pub package package publisher

Provides WebDriver bindings for Dart. These use the WebDriver JSON interface, and as such, require the use of the WebDriver remote server.

Using package:webdriver

In your Dart code, you can use:

import 'package:webdriver/io.dart';

WebDriver driver = createDriver(...);

This will use by default the asynchronous, JSON wire spec implementation. You now can also use a synchronous version of WebDriver:

import 'package:webdriver/sync_io.dart';

final driver = createDriver(...);

This version of WebDriver supports both the JSON wire spec and W3C spec, allowing use with modern versions of Firefox. This defaults to the JSON wire spec, but can also be configured to use the W3C spec or even to try and automatically infer the spec during session creation:

final w3cDriver = createDriver(spec: WebDriverSpec.W3c);  // Use W3C spec.

final anyDriver = createDriver(spec: WebDriverSpec.Auto); // Infer spec.

Testing

Unfortunately using bazel with Dart libraries and Dart WebDriver is not yet supported. We hope to add this at some point, but for now pub still works.

As a consequence, running tests is a bit more complicated than we'd like:

  1. Launch a WebDriver binar(ies).

    First, bring up chromedriver / geckodriver. Other conforming WebDriver binaries should work as well, but we test against these:

    chromedriver --port=4444 --url-base=wd/hub --verbose
    geckodriver --port=4445
    

    ChromeDriver is used to test our JSON wire spec implementation, and geckodriver is used to test our W3C spec implementation.

    Synchronous tests are labeled as Chrome/Firefox. All async tests run exclusively against Chrome (as async, like ChromeDriver supports only the old JSON wire spec).

  2. Run a test. All files suffixed with _test.dart are tests.

    dart test test/path/to/the_test.dart -r expanded -p vm
    

    Or to run all tests:

    dart test -r expanded -p vm
    

    You should probably go get a coffee or something, this is gonna take a while.

webdriver.dart's People

Contributors

blackhc avatar dependabot[bot] avatar devoncarew avatar dramos07 avatar drmarcii avatar goderbauer avatar gramster avatar greglittlefield-wf avatar jingbian avatar jleyba avatar jonahwilliams avatar kevmoo avatar lrhn avatar manuelf avatar mk13 avatar natebosch avatar ochafik avatar sigmundch avatar srawlins avatar staats-google avatar tedsander avatar tijoforyou avatar travissanderson-wf avatar tvolkert avatar vsmenon avatar zachconrad avatar zoechi avatar zoechigist avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

webdriver.dart's Issues

is this package supporting latest webdriver spec?

I am trying to use webdriver.dart and i found this error

Unhandled exception:
InvalidRequestException (400): Bad Request

#0      processJsonWireResponse (package:webdriver/src/sync/json_wire_spec/response_processor.dart:33:5)
#1      SyncHttpCommandProcessor.post (package:webdriver/src/sync/command_processor.dart:57:12)
#2      createDriver (package:webdriver/sync_core.dart:65:34)
#3      createDriver (package:webdriver/sync_io.dart:32:5)
#4      main (file:///home/sclee/Context/___/___/bin/main.dart:138:22)

both w3c spec and json wire shows similar behavior.

Thank you.

rename `desired` to `capabilities`?

In lib/io.dart:

Future<WebDriver> createDriver({Uri uri, Map<String, dynamic> desired})

consider renaming the desired param to capabilities.

pub run test doesn't work with the latest build

Perhaps rename these files if they are not meant to be run directly?

00:00 +0 -1: test/src/alert_test.dart: load error
  Failed to load "test/src/alert_test.dart": No top-level main() function defined.
00:00 +0 -2: test/src/keyboard_test.dart: load error
  Failed to load "test/src/keyboard_test.dart": No top-level main() function defined.
00:00 +1 -3: test/src/logs_test.dart: load error
  Failed to load "test/src/logs_test.dart": No top-level main() function defined.
00:00 +1 -4: test/src/mouse_test.dart: load error
  Failed to load "test/src/mouse_test.dart": No top-level main() function defined.
00:00 +2 -5: test/src/navigation_test.dart: load error
  Failed to load "test/src/navigation_test.dart": No top-level main() function defined.
00:00 +2 -6: test/src/options_test.dart: load error
  Failed to load "test/src/options_test.dart": No top-level main() function defined.
00:00 +2 -7: test/src/target_locator_test.dart: load error
  Failed to load "test/src/target_locator_test.dart": No top-level main() function defined.
00:00 +2 -8: test/src/web_driver_test.dart: load error
  Failed to load "test/src/web_driver_test.dart": No top-level main() function defined.
00:00 +2 -9: test/src/web_element_test.dart: load error
  Failed to load "test/src/web_element_test.dart": No top-level main() function defined.
00:00 +2 -10: test/src/window_test.dart: load error
  Failed to load "test/src/window_test.dart": No top-level main() function defined.

How to drag

I tried

      WebElement startResizeHandle =  await driver.findElement(const By.cssSelector('#handle'));
      expect(startResizeHandle, isNotNull);
      await driver.mouse.moveTo(element: startResizeHandle);
      await driver.mouse.down(Mouse.left);
      await driver.mouse.moveTo(xOffset: 50, yOffset: 0);
      await driver.mouse.up(Mouse.left);

According to the highlighting the mouse seems to move correctly but no drag'n drop is happening. Should this work this way?

issues using this driver with saucelabs and sauce_connect

I'm having trouble getting this driver up and running with saucelabs. I'm using the latest non-dev release, 0.9.1. What I'm seeing is that the result from the commandProcessor.post call in WebDriver.createDriver() is a string, not a valid json encoded map:

"OK,ondemand alive"

Here's the code I'm using:

import 'dart:io';

import 'package:webdriver/webdriver.dart';

main(List args) async {
  if (args.length < 2) {
    print('usage: sauce <username> <accesskey>');
    exit(1);
  }

  String username = args[0];
  String accessKey = args[1];

  Map caps = Capabilities.firefox;
  caps[Capabilities.version] = "17";
  //capabilities.setCapability("platform", Platform.XP);

  String uri = 'http://${username}:${accessKey}@ondemand.saucelabs.com:80/wd/hub';
  print('Connecting to ${uri}...');

  WebDriver driver = await WebDriver.createDriver(
      uri: Uri.parse(uri),
      desiredCapabilities: caps);
  await driver.get("http://www.amazon.com/");
  print(await driver.title);
  driver.close();
}

The code fails when the createDriver call tries to access the sessionId from the http post response, when the value is a string and not a map.

Need to add support for W3C variant of WebDriver API

The W3C WebDriver spec is getting close to CR status, and some endpoints (notably GeckoDriver and EdgeDriver) will only support the new spec. There are some changes that will need to be made to this project to make it work as this transition is made, most notably:

  1. responses no longer include a status field. Instead they include an error field with a text value if an error occurs.

  2. The various low-level actions endpoints (e.g. keyboard and mouse actions) are no longer supported. Instead a single actions endpoint is defined that takes a message representing a sequence of keyboard, mouse, and touch screen actions.

current failures

These are the current failures I see when run with chromedriver on macos:

00:23 +14 -1: Navigation forward/back            
  Expected: contains 'Google'
    Actual: ''

  package:unittest/src/simple_configuration.dart 15:28  _ExpectFailureHandler.fail
  package:matcher/src/expect.dart 121:9                 DefaultFailureHandler.failMatch
  package:matcher/src/expect.dart 95:29                 expect
  test/src/navigation_test.dart 26:19                   main.<fn>.<fn>.<fn>
  dart:isolate                                          _RawReceivePortImpl._handleMessage

00:30 +16 -2: Cookies add complex cookie
  Expected: true
    Actual: <false>

  package:unittest/src/simple_configuration.dart 15:28  _ExpectFailureHandler.fail
  package:matcher/src/expect.dart 121:9                 DefaultFailureHandler.failMatch
  package:matcher/src/expect.dart 95:29                 expect
  test/src/options_test.dart 55:19                      main.<fn>.<fn>.<fn>
  dart:isolate                                          _RawReceivePortImpl._handleMessage

01:41 +61 -3: Window location                          
  Expected: <20>
    Actual: <22>

  package:unittest/src/simple_configuration.dart 15:28  _ExpectFailureHandler.fail
  package:matcher/src/expect.dart 121:9                 DefaultFailureHandler.failMatch
  package:matcher/src/expect.dart 95:29                 expect
  test/src/window_test.dart 38:19                       main.<fn>.<fn>.<fn>
  dart:isolate                                          _RawReceivePortImpl._handleMessage

01:42 +61 -4: Window maximize
  Expected: <0>
    Actual: <22>

  package:unittest/src/simple_configuration.dart 15:28  _ExpectFailureHandler.fail
  package:matcher/src/expect.dart 121:9                 DefaultFailureHandler.failMatch
  package:matcher/src/expect.dart 95:29                 expect
  test/src/window_test.dart 49:21                       main.<fn>.<fn>.<fn>
  dart:isolate                                          _RawReceivePortImpl._handleMessage

01:42 +61 -4: Some tests failed.
61 PASSED, 4 FAILED, 0 ERRORS

Webdriver Help with Waiting for Submitted Form to Process

I'm using webdriver.dart to automate functional testing of a webpage with a back-end script written in GO. Upon submission of the form, the inputted fields get passed to a script implemented in a generation handler. This is done through an action like so:

<form id="fontfileinfo" action="/generate" method="POST" enctype="multipart/form-data">

Once this is complete, the page redirects to another page that displays the status and has its own handler.

However, webdriver keeps trying to navigate to /generate upon submission even though this is not an actual page or url that the user ever sees when done manually. It is simply used for back-end generation. Because of this, the test never reaches the /status page. I have tried waiting for the url to change, elements to become visible, and thread.sleep.

Are there any other options that I'm overlooking?

Allow a custom (extended) WebDriver class

I haven't found a way to create a custom "WebDriver" class or extend WebDriver.

I would like to have an extended WebDriver class with additional methods (for example using common JS snippets with execute()) but I have to copy a lot of code to make it work.

The main problems so far are _CommandProcessor being private and WebElements private constructor. The next problem is probably _WebDriverBase

Add some way to scroll an element

Hi,

I'm writing a test where I want to scroll an element (to test some infinite-scroll logic), but it doesn't look like there's any built-in way of doing that. The Mouse class doesn't seem to expose anything; there's a scroll method in the Touch class, but using that fails with "Underlying driver does not implement advanced user interactions yet.".

I can work around it by modifying the element's scrollTop manually, but it'd be nice to have something that'd trigger all the proper mouse/touch events.

Add back captureScreenshotAsBase64

The sync webdriver provides both captureScreenshot and captureScreenshotAsBase64.

Atm:

  /// Take a screenshot of the current page as PNG.
  Stream<int> captureScreenshot() async* {
    var encoded = await getRequest('screenshot');
    yield* new Stream.fromIterable(CryptoUtils.base64StringToBytes(encoded));
  }

This could be split up again into two methods.

PUT request

Looks like there is no any possibility to perfrom PUT (and any others HEAD, OPTIONS) http requests.
Exposed generic method "request( String method, Uri uri, [Map params] )" solved the issue completely.

Use element acquired by driver.execute

I look up elements using

var elements = await driver.execute('return document.querySelector('someSelector')
    .shadowRoot.querySelectorAll("otherSelector");', []).toList();
var cell = elements[3];
var text = await cell.text;
await cell.click();

The last line results in

StaleElementReferenceException (10): stale element reference: element is not attached to the page document
(Session info: chrome=44.0.2403.157)
(Driver info: chromedriver=2.19.346067 (6abd8652f8bc7a1d825962003ac88ec6a37a82f1),platform=Linux 4.1.0-1-amd64 x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 16 milliseconds
For documentation on this error, please visit: http://seleniumhq.org/exceptions/stale_element_reference.html
Build info: version: '2.47.1', revision: '411b314', time: '2015-07-30 03:03:16'
System info: host: '7705b8531113', ip: '172.17.1.91', os.name: 'Linux', os.arch: 'amd64', os.version: '4.1.0-1-amd64', java.version: '1.8.0_45-internal'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities [{applicationCacheEnabled=false, rotatable=false, mobileEmulationEnabled=false, chrome={userDataDir=/tmp/.com.google.Chrome.F3Ryk6}, takesHeapSnapshot=true, databaseEnabled=false, handlesAlerts=true, hasTouchScreen=false, version=44.0.2403.157, platform=LINUX, browserConnectionEnabled=false, nativeEvents=true, acceptSslCerts=true, locationContextEnabled=true, webStorageEnabled=true, browserName=chrome, takesScreenshot=true, javascriptEnabled=true, cssSelectorsEnabled=true}]
Session ID: f10548f173186772ad19f62227f175c5
package:webdriver WebElement.click

The same test worked previously with findElements(const By.cssSelector('selector /deep/ otherSelector')); but this isn't supported in browsers except Chrome.

Should this work?
Could this be an issue in this package or is this an issue of the ChromeDriver?

3 failures on mac (with chrome driver)

00:53 +25 -1: WebDriver create default
  Test failed: Caught 13 Unknown: Connection refused
  An unknown server-side error occurred while processing the command.
  package:webdriver/src/web_driver.dart 59:15  WebDriver.createDriver.<fn>.<fn>
  dart:async                                   _createTimer.<fn>
  timer_impl.dart 96:21                        _Timer._createTimerHandler._handleTimeout
  timer_impl.dart 112:23                       _Timer._createTimerHandler.<fn>
  dart:isolate                                 _ReceivePortImpl._handleMessage

02:10 +62 -2: Window location
  Expected: <20>
    Actual: <22>

  package:unittest/src/expect.dart 75:29  expect
  test/src/window_test.dart 35:21         WindowTest.main.<fn>.<fn>.<fn>
  dart:async                              _createTimer.<fn>
  timer_impl.dart 96:21                   _Timer._createTimerHandler._handleTimeout
  timer_impl.dart 112:23                  _Timer._createTimerHandler.<fn>
  dart:isolate                            _ReceivePortImpl._handleMessage

02:12 +62 -3: Window maximize
  Expected: <0>
    Actual: <26>

  package:unittest/src/expect.dart 75:29  expect
  test/src/window_test.dart 46:23         WindowTest.main.<fn>.<fn>.<fn>
  dart:async                              _createTimer.<fn>
  timer_impl.dart 96:21                   _Timer._createTimerHandler._handleTimeout
  timer_impl.dart 112:23                  _Timer._createTimerHandler.<fn>
  dart:isolate                            _ReceivePortImpl._handleMessage

02:13 +62 -3: Some tests failed.
62 PASSED, 2 FAILED, 1 ERRORS

WebDriver - create - default: fails on mac

WebDriver create default
  Test failed: Caught 13 Unknown: Connection refused
  An unknown server-side error occurred while processing the command.
  package:webdriver/src/web_driver.dart 59:15  WebDriver.createDriver.<fn>.<fn>
  dart:async                                   _createTimer.<fn>
  timer_impl.dart 96:21                        _Timer._createTimerHandler._handleTimeout
  timer_impl.dart 112:23                       _Timer._createTimerHandler.<fn>
  dart:isolate                                 _ReceivePortImpl._handleMessage

Typo: NoAlertPresentException vs. NoAlertOpenException

https://github.com/google/webdriver.dart/blob/master/lib/src/target_locator.dart says:

/// Throws [NoAlertPresentException] if there is not currently an alert.

However,
https://github.com/google/webdriver.dart/blob/master/lib/src/exception.dart says:

        case 27: // NoAlertOpenError
          return new NoAlertOpenException(status, message);

Java WebDriver exception name is NoAlertPresentException.
http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/NoAlertPresentException.html

I prefer to use NoAlertPresentException, because it is also used in Java version. However, if you want to stick to use NoAlertOpenException, please fix the comment. Thanks!

WebDriver.get doesn't work

final url = 'http://localhost:${examplePubServePort}/testing/index.html';

// await driver.navigate.to(url); 
await driver.get(url); 

final WebElement someDiv =
          await driver.findElement(const By.cssSelector('* /deep/ #some-div'));
// fails with PhantomJS (with driver.get()): InvalidElementStateException (12): {"errorMessage":"SyntaxError: DOM Exception 12"
// fails with Chrome (with driver.get()): NoSuchElementException (7): no such element
// succeeds with driver.navigate.to() with Chrome and PhantomJS

expect(title, equals('browser/webdriver test'));
expect(someDiv, isNotNull);

await someDiv.attributes['id'] 
// fails with PhantomJs with driver.navigate.to()
// > StaleElementReferenceException (10): {"errorMessage":"Element does not exist in cache"
// succeeds with Chrome with driver.navigate.to()

driver.get and WebElement.attributes[] call CommandProcessor.get() while driver.navigate.to() calls CommandProcessor.post()
I think driver.findElement() fails because driver.get() doesn't do anything and times out.
In Chrome I see the URL and the page load when driver.navigate.to() is used. With driver.get the URL is just data:, and nothing else happens.

Am I doing something wrong or is this a bug?
driver.get() and driver.navigate.to() are supposed to do the same thing, aren't they?

Dart VM version: 1.11.0-edge.45304 (Mon Apr 20 18:15:39 2015) on "linux_x64"

Slow async captureScreenshot

async captureScreenshot is about ~40x slower than the synchronous version (taking a 800x600 screenshot takes ~20s vs 500ms). This is because captureScreenshot returns a Stream containing the bytes making up the png screenshot and we have to call Stream.toList() to write the screenshot to a file. Compared to returning the list directly, it is 5000x slower in a test. (100x slower because of wrapping it in a Stream and async_/yield_ and 50x slower because of unittest & stack_trace).

The suggested solution is to add a captureScreenshotAsList method back that returns a simple List.
See also captureScreenshotAsBase64 #112

Unable to upload files to remote WebDrivers

We are not able to upload files on file input elements on remote services like Sauce Labs.
This is normally done by sending keys to the element. The Dart client doesn't appear to upload the file to remote services first like the others do. Python Example

If the keys being sent to an element are found to be a path that points to a local file, the file is upload to the WebDriver with a POST request to /session/$sessionId/file, and the response to that request is what's actually sent to the element.

  • Dart version: 1.9.0-dev.8.0
  • OS: OS X 10.10.3
  • Dart webdriver version: 0.9.1

1.2.4 is not published, published version of 1.2.3 does not match tag

I'm looking to use the FutureOr<T> version of waitFor, which was added in version 1.2.3 of this package: https://github.com/google/webdriver.dart/blob/v1.2.3/lib/support/async.dart#L28

However, that change doesn't seem to be present in the Pub archive of 1.2.3: https://storage.googleapis.com/pub-packages/packages/webdriver-1.2.3.tar.gz

While looking into this, I also noticed that 1.2.4 was tagged but not published (see published versions here: https://pub.dartlang.org/packages/webdriver#pub-pkg-tab-versions).

Support for MutableCapabilities and ImmutableCapabilities

Problem: After updating from Selenium v3.6.0 to Selenium v3.8.1, the capabilities don't appear to work as expected. For example, downloads are no longer going to/shared/exports using the snippet below.

    Map capabilities = {
      'platform': 'LINUX',
      'browserName': 'chrome',
      'chromeOptions': {
        'args': ['window-size=1280,600', 'disable-infobars', 'enable-precise-memory-info'],
        'prefs': {
          'download': {'default_directory': '/shared/exports/', 'prompt_for_download': 'false'}
        }
      }
    }
  driver = await io.createDriver(desired: capabilities, uri: seleniumUri);
  • The version of Dart on your system: Dart VM version: 1.24.2 (Thu Jun 22 15:42:21 2017) on "linux_x64"
  • The operating system you are running: linux_x64
  • The version of the webdriver package you are using: 1.2.3

I assume the web driver implementation will need to support MutableCapabilities and ImmutableCapabilities?

Enable generics in waitFor

For consuming libraries to obey strong mode, we will need to enable the commented-out generics in the waitFor definition here. This would require bumping the SDK restriction to 1.21+. Is this a change you would be open to accepting?

2 of 3 Window tests fail on Mac

Likely platform differences?

PASS: Window size
FAIL: Window location
  Expected: <20>
    Actual: <22>

  package:unittest/src/expect.dart 75:29  expect
  test/src/window_test.dart 38:19         main.<fn>.<fn>.<fn>
  dart:async                              _createTimer.<fn>
  timer_impl.dart 96:21                   _Timer._createTimerHandler._handleTimeout
  timer_impl.dart 112:23                  _Timer._createTimerHandler.<fn>
  dart:isolate                            _ReceivePortImpl._handleMessage
FAIL: Window maximize
  Expected: <0>
    Actual: <26>

  package:unittest/src/expect.dart 75:29  expect
  test/src/window_test.dart 49:21         main.<fn>.<fn>.<fn>
  dart:async                              _createTimer.<fn>
  timer_impl.dart 96:21                   _Timer._createTimerHandler._handleTimeout
  timer_impl.dart 112:23                  _Timer._createTimerHandler.<fn>
  dart:isolate                            _ReceivePortImpl._handleMessage

1 PASSED, 2 FAILED, 0 ERRORS

Get rid of deprecated captureScreenShot

/// Take a screenshot of the current page as PNG as stream of uint8.
///
/// Don't use this method. Prefer [captureScreenshotAsBase64] or
/// [captureScreenshotAsList]. Returning the data as Stream<int> can be very
/// slow.
@Deprecated('Use captureScreenshotAsBase64 or captureScreenshotAsList!')
Stream<int> captureScreenshot() async* {
yield* new Stream.fromIterable(await captureScreenshotAsList());
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.