Skip to content

Commit

Permalink
Merge pull request #27 from DrMarcII/master
Browse files Browse the repository at this point in the history
Add option to disable shadowDom support.
  • Loading branch information
DrMarcII committed Feb 4, 2015
2 parents d06863c + e18b912 commit 4f528e3
Show file tree
Hide file tree
Showing 12 changed files with 368 additions and 26 deletions.
31 changes: 21 additions & 10 deletions dart/lib/html.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,19 @@ class HtmlPageLoader extends BasePageLoader {
@override
_HtmlMouse get mouse => _mouse;

factory HtmlPageLoader(Node globalContext, [SyncActionFn syncActionFn]) {
factory HtmlPageLoader(Node globalContext,
{SyncActionFn syncActionFn, bool useShadowDom: true}) {
var clock;

if (syncActionFn != null) {
clock = new _SyncActionClock(syncActionFn);
}

return new HtmlPageLoader._(globalContext, clock);
return new HtmlPageLoader._(globalContext, clock, useShadowDom);
}

HtmlPageLoader._(Node globalContext, Clock clock) : super(clock) {
HtmlPageLoader._(Node globalContext, Clock clock, bool useShadowDom)
: super(clock: clock, useShadowDom: useShadowDom) {
this._globalContext = new HtmlPageLoaderElement(globalContext, this);
this._mouse = new _HtmlMouse(this);
}
Expand Down Expand Up @@ -107,9 +109,10 @@ class _HtmlMouse implements PageLoaderMouse {
int get pageY => window.pageYOffset + clientY;
int get _borderWidth => (window.outerWidth - window.innerWidth) ~/ 2;
int get screenX => window.screenLeft + _borderWidth + clientX;
int get screenY => window.screenTop + window.outerHeight -
window.innerHeight -
_borderWidth +
int get screenY => window.screenTop +
window.outerHeight -
window.innerHeight -
_borderWidth +
clientY;

void dispatchEvent(String type, _ElementPageLoaderElement eventTarget,
Expand Down Expand Up @@ -149,7 +152,12 @@ abstract class HtmlPageLoaderElement implements PageLoaderElement {
} else if (node is Document) {
return new _DocumentPageLoaderElement(node, loader);
} else if (node is ShadowRoot) {
return new _ShadowRootPageLoaderElement(node, loader);
if (loader.useShadowDom) {
return new _ShadowRootPageLoaderElement(node, loader);
} else {
throw new PageLoaderException(
'Cannot create element for ShadowRoot when useShadowDom is false');
}
}
return null;
}
Expand Down Expand Up @@ -211,8 +219,9 @@ class _ElementPageLoaderElement extends HtmlPageLoaderElement {
this.style = new _ElementStyle(_node);

@override
PageLoaderElement get shadowRoot =>
new HtmlPageLoaderElement(node.shadowRoot, loader);
PageLoaderElement get shadowRoot => loader.useShadowDom
? new HtmlPageLoaderElement(node.shadowRoot, loader)
: this;
@override
String get name => node.tagName.toLowerCase();
// TODO(DrMarcII): implement this to recurse up the tree to see if displayed
Expand Down Expand Up @@ -268,7 +277,9 @@ class _ElementPageLoaderElement extends HtmlPageLoaderElement {
class _ShadowRootPageLoaderElement extends HtmlPageLoaderElement {
final ShadowRoot node;

_ShadowRootPageLoaderElement(this.node, PageLoader loader) : super._(loader);
_ShadowRootPageLoaderElement(this.node, PageLoader loader) : super._(loader) {
assert(loader.useShadowDom);
}

@override
String get name => '__shadow_root__';
Expand Down
8 changes: 5 additions & 3 deletions dart/lib/src/core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ const _DEFAULT_INTERVAL = const Duration(milliseconds: 100);
/// fields in simple Dart objects.
abstract class BasePageLoader implements PageLoader {
final Clock clock;
final bool useShadowDom;

BasePageLoader([Clock clock])
BasePageLoader({Clock clock, this.useShadowDom: true})
: this.clock = clock == null ? new FakeClock() : clock;

/// Creates a new instance of [type] and binds annotated fields to
Expand All @@ -50,7 +51,7 @@ abstract class BasePageLoader implements PageLoader {

@override
waitForValue(condition(), {Duration timeout: _DEFAULT_WAIT,
Duration interval: _DEFAULT_INTERVAL}) =>
Duration interval: _DEFAULT_INTERVAL}) =>
waitFor(condition, isNotNull, timeout: timeout, interval: interval);

@override
Expand Down Expand Up @@ -351,7 +352,8 @@ class _FinderSingleFieldInfo extends _FinderFieldInfo {
final bool _isOptional;

_FinderSingleFieldInfo(Symbol fieldName, this._finder, this._filters,
this._instanceType, this._isOptional) : super(fieldName);
this._instanceType, this._isOptional)
: super(fieldName);

@override
calculateFieldValue(PageLoaderElement context, BasePageLoader loader) {
Expand Down
1 change: 1 addition & 0 deletions dart/lib/src/interfaces.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ abstract class Lazy<T> {
}

abstract class PageLoader {
bool get useShadowDom;
PageLoaderElement get globalContext;

Object getInstance(Type type, [dynamic context]);
Expand Down
9 changes: 4 additions & 5 deletions dart/lib/webdriver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,11 @@ import 'package:sync_webdriver/sync_webdriver.dart' as wd;

class WebDriverPageLoader extends BasePageLoader {
WebDriverPageLoaderElement _globalContext;
final bool useShadowRoot;
@override
final _WebDriverMouse mouse;

WebDriverPageLoader(wd.SearchContext globalContext,
{this.useShadowRoot: true})
: super(const _IOClock()),
WebDriverPageLoader(wd.SearchContext globalContext, {useShadowDom: true})
: super(clock: const _IOClock(), useShadowDom: useShadowDom),
this.mouse = new _WebDriverMouse(globalContext.driver) {
this._globalContext = new WebDriverPageLoaderElement(globalContext, this);
}
Expand Down Expand Up @@ -153,7 +151,7 @@ class _WebElementPageLoaderElement extends WebDriverPageLoaderElement {

@override
WebDriverPageLoaderElement get shadowRoot {
if (loader.useShadowRoot) {
if (loader.useShadowDom) {
return new _ShadowRootPageLoaderElement(context, loader);
} else {
return this;
Expand Down Expand Up @@ -231,6 +229,7 @@ class _ShadowRootPageLoaderElement extends WebDriverPageLoaderElement {

_ShadowRootPageLoaderElement(this.context, WebDriverPageLoader loader)
: super._(loader) {
assert(loader.useShadowDom);
if (!_execute(' != null')) {
throw new PageLoaderException('$context does not have a ShadowRoot');
}
Expand Down
5 changes: 3 additions & 2 deletions dart/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
name: pageloader
version: 1.2.6
version: 1.3.0
author: Marc Fisher II
description: Supports the creation of page objects that can be shared between in-browser tests and WebDriver tests.
environment:
sdk: '>=1.9.0-dev.4.0 <2.0.0'
dependencies:
matcher: '^0.11.4'
sync_webdriver:
path: ../../dart-sync-webdriver
dev_dependencies:
browser: '^0.10.0+2'
path: '^1.3.1'
path: '^1.3.2'
unittest: '^0.11.5'
141 changes: 141 additions & 0 deletions dart/test/no_shadow_dom_html_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/*
* Copyright 2014 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.
*/
library pageloader.test.html;

import 'page_objects.dart';
import 'pageloader_test.dart' as plt;

import 'package:pageloader/html.dart';
import 'package:unittest/html_enhanced_config.dart';
import 'package:unittest/unittest.dart';

import 'dart:html' as html;

void main() {
useHtmlEnhancedConfiguration();

setUp(() {
var body = html.document.getElementsByTagName('body').first;
const bodyHtml = '''
<style>
.class1 { background-color: #00FF00; }
</style>
<table id='table1' non-standard='a non standard attr'
class='class1 class2 class3' style='color: #800080;'>
<tr>
<td>r1c1</td>
<td>r1c2</td>
</tr>
<tr>
<td>r2c1</td>
<td>r2c2</td>
</tr>
</table>
<div id='div' style='display: none; background-color: red;'>
some not displayed text</div>
<div id='mouse'>area for mouse events</div>
<input type='text' id='text' />
<input type='text' readonly id='readonly' disabled />
<input type='checkbox' class='with-class-test class1 class2' />
<input type='radio' name='radio' value='radio1' />
<input type='radio' name='radio' value='radio2' />
<a href="test.html" id="anchor">test</a>
<img src="test.png">
<select id='select1'>
<option id='option1' value='value 1'>option 1</option>
<option id='option2' value='value 2'>option 2</option>
</select>
<textarea id='textarea'></textarea>
<div class="outer-div">
outer div 1
<a-custom-tag><button id="inner">some </button></a-custom-tag>
</div>
<div class="outer-div">
outer div 2
<div class="inner-div">
inner div 1
</div>
<div class="inner-div special">
inner div 2
</div>
</div>
<a-custom-tag id="button-1">
<button id="inner">some button 1</button>
</a-custom-tag>
<a-custom-tag id="button-2">
<button id="inner">some button 2</button>
</a-custom-tag>''';

var div = body.querySelectorAll('div[id=testdocument]');
if (div.length == 1) {
div = div[0];
} else {
div = new html.DivElement();
div.id = 'testdocument';
body.append(div);
}
div.setInnerHtml(bodyHtml, validator: new NoOpNodeValidator());

var displayedDiv = html.document.getElementById('mouse');
displayedDiv.onMouseDown.listen((evt) {
displayedDiv.text = displayedDiv.text +
" MouseDown: ${evt.client.x}, ${evt.client.y}; "
"${evt.screen.x}, ${evt.screen.y}";
});
displayedDiv.onMouseUp.listen((evt) {
displayedDiv.text = displayedDiv.text +
" MouseUp: ${evt.client.x}, ${evt.client.y}; "
"${evt.screen.x}, ${evt.screen.y}";
});
displayedDiv.onMouseMove.listen((evt) {
displayedDiv.text = displayedDiv.text +
" MouseMove: ${evt.client.x}, ${evt.client.y}; "
"${evt.screen.x}, ${evt.screen.y}";
});

plt.loader = new HtmlPageLoader(div, useShadowDom: false);
});

group('html specific tests', () {
test('value on text', () {
var page = plt.loader.getInstance(PageForAttributesTests);
var handlerCalled = false;
var node = (page.text as HtmlPageLoaderElement).node as html.InputElement;
node.onInput.listen((event) {
handlerCalled = true;
});
expect(page.text.attributes['value'], '');
page.text.type('some text');
expect(page.text.attributes['value'], 'some text');
expect(handlerCalled, isTrue);
});

test('keypress events', () {
var data = 'my data';
var list = [];
html.document.body.onKeyPress.listen((evt) => list.add(evt.charCode));
plt.loader.globalContext.type(data);
expect(new String.fromCharCodes(list), equals(data));
});
});

plt.runTests();
}

class NoOpNodeValidator implements html.NodeValidator {
bool allowsAttribute(
html.Element element, String attributeName, String value) => true;
bool allowsElement(html.Element element) => true;
}
16 changes: 16 additions & 0 deletions dart/test/no_shadow_dom_html_test.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!DOCTYPE html>

<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>no_shadow_dom_html_test</title>
</head>

<body>
<script type="application/dart" src="no_shadow_dom_html_test.dart"></script>
<!-- for this next line to work, your pubspec.yaml file must have a
dependency on 'browser' -->
<script src="packages/browser/dart.js"></script>
</body>
</html>
25 changes: 20 additions & 5 deletions dart/test/pageloader_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,9 @@ void runTests() {
expect(page.button1.button.visibleText, contains('some'));
expect(page.button2.button.visibleText, contains('button 2'));
expect(page.button2.button.visibleText, contains('some'));
expect(page.shouldBeEmpty, isEmpty);
if (loader.useShadowDom) {
expect(page.shouldBeEmpty, hasLength(0));
}
});

test('WithVisibleText in shadow dom', () {
Expand All @@ -239,8 +241,6 @@ void runTests() {

expect(page.button1.visibleText, contains('button 1'));
expect(page.button1.visibleText, contains('some'));
expect(page.button1.innerText, contains('button 1'));
expect(page.button1.innerText, isNot(contains('some')));
});

test('chain', () {
Expand All @@ -254,6 +254,11 @@ void runTests() {
});

test('WithInnerText in shadow dom', () {
if (!loader.useShadowDom) {
// if shadow dom is disabled, then visibleText and innerText are
// identical
return;
}
PageForShadowDomWithInnerTextTest page =
loader.getInstance(PageForShadowDomWithInnerTextTest);

Expand All @@ -273,9 +278,19 @@ void runTests() {
expect(page.buttons[1].shadowRoot.visibleText, contains('some'));
expect(page.buttons[2].shadowRoot.visibleText, contains('button 2'));
expect(page.buttons[2].shadowRoot.visibleText, contains('some'));
expect(page.buttons[1].shadowRoot.innerText, isNot(contains('button 1')));
if (loader.useShadowDom) {
expect(
page.buttons[1].shadowRoot.innerText, isNot(contains('button 1')));
} else {
expect(page.buttons[1].shadowRoot.innerText, contains('button 1'));
}
expect(page.buttons[1].shadowRoot.innerText, contains('some'));
expect(page.buttons[2].shadowRoot.innerText, isNot(contains('button 2')));
if (loader.useShadowDom) {
expect(
page.buttons[2].shadowRoot.innerText, isNot(contains('button 2')));
} else {
expect(page.buttons[2].shadowRoot.innerText, contains('button 2'));
}
expect(page.buttons[2].shadowRoot.innerText, contains('some'));
});

Expand Down
Loading

0 comments on commit 4f528e3

Please sign in to comment.