Corrects issues with W3c spec implementation for web element against Firefox. (#165)
* Corrects issues with W3c spec implementation against Firefox. Adds test specific to W3c spec. Extends web_element to account for properties.
* Move comment to avoid bizarre formatting.
diff --git a/lib/src/sync/json_wire_spec/web_element.dart b/lib/src/sync/json_wire_spec/web_element.dart
index f27ccef..6ecbaaf 100644
--- a/lib/src/sync/json_wire_spec/web_element.dart
+++ b/lib/src/sync/json_wire_spec/web_element.dart
@@ -124,6 +124,10 @@
new Attributes(driver, '$_elementPrefix/attribute');
@override
+ Attributes get properties =>
+ new Attributes(driver, '$_elementPrefix/property');
+
+ @override
Attributes get cssProperties => new Attributes(driver, '$_elementPrefix/css');
@override
diff --git a/lib/src/sync/w3c_spec/web_element.dart b/lib/src/sync/w3c_spec/web_element.dart
index d7fe13f..8282da4 100644
--- a/lib/src/sync/w3c_spec/web_element.dart
+++ b/lib/src/sync/w3c_spec/web_element.dart
@@ -58,13 +58,13 @@
// TODO(staats): tie this into actions API support.
void sendKeys(String keysToSend) {
_resolver.post('value', {
- 'text': [keysToSend],
- 'keyboard': ''
+ 'text': keysToSend, // What geckodriver really wants.
+ 'value': keysToSend // Actual W3C spec.
});
}
@override
- void clear() => _resolver.post('clear');
+ void clear() => _resolver.post('clear', {});
@override
bool get selected => _resolver.get('selected') as bool;
@@ -74,10 +74,7 @@
@override
// TODO(staats): add many, many tests here.
- bool get displayed {
- final style = _resolver.get('property/getComputedStyle');
- return style['display'] != 'none';
- }
+ bool get displayed => this.cssProperties['display'] != 'none';
@override
// TODO(staats): better exception.
@@ -111,12 +108,17 @@
new Attributes(driver, '$_elementPrefix/attribute');
@override
+ Attributes get properties =>
+ new Attributes(driver, '$_elementPrefix/property');
+
+ @override
Attributes get cssProperties => new Attributes(driver, '$_elementPrefix/css');
// TODO(staats): add support for properties to WebElement.
@override
- bool equals(WebElement other) => _resolver.get('equals/${other.id}') as bool;
+ bool equals(WebElement other) =>
+ other is W3cWebElement && other.id == this.id;
@override
Map<String, String> toJson() => {elementStr: id};
diff --git a/lib/src/sync/web_element.dart b/lib/src/sync/web_element.dart
index f5cd235..63bf0ce 100644
--- a/lib/src/sync/web_element.dart
+++ b/lib/src/sync/web_element.dart
@@ -87,6 +87,9 @@
/// Access to the HTML attributes of this tag.
Attributes get attributes;
+ /// Access to the HTML properties of this tag.
+ Attributes get properties;
+
/// Access to the cssProperties of this element.
Attributes get cssProperties;
diff --git a/test/firefox_web_element_test.dart b/test/firefox_web_element_test.dart
new file mode 100644
index 0000000..e9bd1d7
--- /dev/null
+++ b/test/firefox_web_element_test.dart
@@ -0,0 +1,20 @@
+// Copyright 2017 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import 'sync/w3c_web_element.dart';
+import 'sync/sync_io_config.dart' as config;
+
+void main() {
+ runTests(config.createFirefoxTestDriver);
+}
diff --git a/test/sync/w3c_web_element.dart b/test/sync/w3c_web_element.dart
new file mode 100644
index 0000000..5157063
--- /dev/null
+++ b/test/sync/w3c_web_element.dart
@@ -0,0 +1,178 @@
+// Copyright 2015 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+@TestOn("vm")
+library webdriver.web_element_test;
+
+import 'dart:io';
+
+import 'package:test/test.dart';
+import 'package:webdriver/sync_core.dart';
+
+import 'sync_io_config.dart' as config;
+
+/// Tests specific to the W3C spec for WebElement. There are significant
+/// differences between the JSON and W3C specs here.
+void runTests(config.createTestDriver createTestDriver) {
+ group('WebElement', () {
+ WebDriver driver;
+ WebElement table;
+ WebElement button;
+ WebElement form;
+ WebElement textInput;
+ WebElement checkbox;
+ WebElement disabled;
+ WebElement invisible;
+
+ setUp(() {
+ driver = createTestDriver();
+ driver.get(config.testPagePath);
+ table = driver.findElement(const By.tagName('table'));
+ button = driver.findElement(const By.tagName('button'));
+ form = driver.findElement(const By.tagName('form'));
+ textInput = driver.findElement(const By.cssSelector('input[type=text]'));
+ checkbox =
+ driver.findElement(const By.cssSelector('input[type=checkbox]'));
+ disabled =
+ driver.findElement(const By.cssSelector('input[type=password]'));
+ invisible = driver.findElement(const By.tagName('div'));
+ });
+
+ tearDown(() {
+ if (driver != null) {
+ driver.quit();
+ }
+ driver = null;
+ });
+
+ test('click', () {
+ button.click();
+ var alert = driver.switchTo.alert;
+ alert.accept();
+ });
+
+ test('sendKeys', () {
+ textInput.sendKeys('some keys');
+ sleep(new Duration(milliseconds: 500));
+ expect(textInput.properties['value'], 'some keys');
+ });
+
+ test('clear', () {
+ textInput.sendKeys('some keys');
+ textInput.clear();
+ expect(textInput.properties['value'], '');
+ });
+
+ test('enabled', () {
+ expect(table.enabled, isTrue);
+ expect(button.enabled, isTrue);
+ expect(form.enabled, isTrue);
+ expect(textInput.enabled, isTrue);
+ expect(checkbox.enabled, isTrue);
+ expect(disabled.enabled, isFalse);
+ });
+
+ test('displayed', () {
+ expect(table.displayed, isTrue);
+ expect(button.displayed, isTrue);
+ expect(form.displayed, isTrue);
+ expect(textInput.displayed, isTrue);
+ expect(checkbox.displayed, isTrue);
+ expect(disabled.displayed, isTrue);
+ expect(invisible.displayed, isFalse);
+ });
+
+ test('rect -- table', () {
+ var location = table.rect;
+ expect(location, config.isRectangle);
+ expect(location.left, isNonNegative);
+ expect(location.top, isNonNegative);
+ expect(location.width, isNonNegative);
+ expect(location.height, isNonNegative);
+ });
+
+ test('location -- invisible', () {
+ var location = invisible.rect;
+ expect(location, config.isRectangle);
+ expect(location.left, 0);
+ expect(location.top, 0);
+ expect(location.width, 0);
+ expect(location.height, 0);
+ });
+
+ test('name', () {
+ expect(table.name, 'table');
+ expect(button.name, 'button');
+ expect(form.name, 'form');
+ expect(textInput.name, 'input');
+ });
+
+ test('text', () {
+ expect(table.text, 'r1c1 r1c2\nr2c1 r2c2');
+ expect(button.text, 'button');
+ expect(invisible.text, '');
+ });
+
+ test('findElement -- success', () {
+ var element = table.findElement(const By.tagName('tr'));
+ expect(element, config.isSyncWebElement);
+ });
+
+ test('findElement -- failure', () {
+ try {
+ button.findElement(const By.tagName('tr'));
+ throw 'Expected Exception';
+ } on Exception {}
+ });
+
+ test('findElements -- 1 found', () {
+ var elements =
+ form.findElements(const By.cssSelector('input[type=text]')).toList();
+ expect(elements, hasLength(1));
+ expect(elements, everyElement(config.isSyncWebElement));
+ });
+
+ test('findElements -- 4 found', () {
+ var elements = table.findElements(const By.tagName('td')).toList();
+ expect(elements, hasLength(4));
+ expect(elements, everyElement(config.isSyncWebElement));
+ });
+
+ test('findElements -- 0 found', () {
+ var elements = form.findElements(const By.tagName('td')).toList();
+ expect(elements, isEmpty);
+ });
+
+ test('attributes', () {
+ expect(table.attributes['id'], 'table1');
+ expect(table.attributes['non-standard'], 'a non standard attr');
+ expect(table.attributes['disabled'], isNull);
+ expect(disabled.attributes['disabled'], 'true');
+ });
+
+ test('cssProperties', () {
+ expect(invisible.cssProperties['display'], 'none');
+ final backgroundColor = invisible.cssProperties['background-color'];
+ expect(backgroundColor, contains('255, 0, 0'));
+ expect(backgroundColor, startsWith('rgb'));
+ expect(invisible.cssProperties['direction'], 'ltr');
+ });
+
+ test('equals', () {
+ expect(invisible.equals(disabled), isFalse);
+ var element = driver.findElement(const By.cssSelector('table'));
+ expect(element.equals(table), isTrue);
+ });
+ }, timeout: new Timeout(new Duration(minutes: 2)));
+}