Skip to content
This repository has been archived by the owner on Jul 29, 2024. It is now read-only.

Commit

Permalink
feat(locators): add by.deepCss selector for finding elements in the s…
Browse files Browse the repository at this point in the history
…hadow dom

Usage:
    element(by.deepCss('.foo'))
    equivalent to 'element(by.css('* /deep/ .foo'))
  • Loading branch information
juliemr committed Feb 16, 2015
1 parent 2658865 commit d220ecf
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 0 deletions.
23 changes: 23 additions & 0 deletions lib/locators.js
Original file line number Diff line number Diff line change
Expand Up @@ -428,4 +428,27 @@ ProtractorBy.prototype.options = function(optionsDescriptor) {
};
};

/**
* Find an element by css selector within the Shadow DOM.
*
* @alias by.deepCss(selector)
* @view
* <div>
* <span id="outerspan">
* <"shadow tree">
* <span id="span1"></span>
* <"shadow tree">
* <span id="span2"></span>
* </>
* </>
* </div>
* @example
* spans = element.all(by.deepCss('span'));
* expect(spans.count()).toEqual(3);
*/
ProtractorBy.prototype.deepCss = function(selector) {
// return webdriver.By.css('* >>> ' + selector);
return webdriver.By.css('* /deep/ ' + selector);
};

exports.ProtractorBy = ProtractorBy;
23 changes: 23 additions & 0 deletions spec/basic/locators_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,29 @@ describe('locators', function() {
});
});

describe('by deep css', function() {
beforeEach(function() {
browser.get('index.html#/shadow');
});

it('should find items inside the shadow DOM', function() {
var parentHeading = element(by.deepCss('.parentshadowheading'));
var olderChildHeading = element(by.deepCss('.oldershadowheading'));
var youngerChildHeading = element(by.deepCss('.youngershadowheading'));

expect(parentHeading.isPresent()).toBe(true);
expect(olderChildHeading.isPresent()).toBe(true);
expect(youngerChildHeading.isPresent()).toBe(true);

expect(parentHeading.getText()).toEqual('Parent');
expect(olderChildHeading.getText()).toEqual('Older Child');
expect(youngerChildHeading.getText()).toEqual('Younger Child');

expect(element(by.deepCss('.originalcontent')).getText())
.toEqual('original content');
});
});

it('should determine if an element is present', function() {
expect(browser.isElementPresent(by.binding('greet'))).toBe(true);
expect(browser.isElementPresent(by.binding('nopenopenope'))).toBe(false);
Expand Down
1 change: 1 addition & 0 deletions testapp/alt_root_index.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
<script src="repeater/repeater.js"></script>
<script src="animation/animation.js"></script>
<script src="interaction/interaction.js"></script>
<script src="shadow/shadow.js"></script>
<script src="app.js"></script>
</body>
</html>
1 change: 1 addition & 0 deletions testapp/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ angular.module('myApp', ['ngAnimate', 'ngRoute', 'myApp.appVersion']).
$routeProvider.when('/polling', {templateUrl: 'polling/polling.html', controller: PollingCtrl});
$routeProvider.when('/animation', {templateUrl: 'animation/animation.html', controller: AnimationCtrl});
$routeProvider.when('/interaction', {templateUrl: 'interaction/interaction.html', controller: InteractionCtrl});
$routeProvider.when('/shadow', {templateUrl: 'shadow/shadow.html', controller: ShadowCtrl});
$routeProvider.when('/slowloader', {
templateUrl: 'polling/polling.html',
controller: PollingCtrl,
Expand Down
2 changes: 2 additions & 0 deletions testapp/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<li><a href="#/polling">polling</a></li>
<li><a href="#/animation">animation</a></li>
<li><a href="#/interaction">interaction</a></li>
<li><a href="#/shadow">shadow dom</a></li>
</ul>

<div ng-view></div>
Expand All @@ -35,6 +36,7 @@
<script src="repeater/repeater.js"></script>
<script src="animation/animation.js"></script>
<script src="interaction/interaction.js"></script>
<script src="shadow/shadow.js"></script>
<script src="app.js"></script>

</body>
Expand Down
42 changes: 42 additions & 0 deletions testapp/shadow/shadow.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<H1>Elements in shadow DOM</H1>
<p>Inspired by ChromeDriver's page for shadow dom webdriver tests. The page has a shadow root that in turn contains two shadow roots. So we can check behaviour with both nested roots and younger/older sibling roots.
<div>
<div id="innerDiv" style="border-style:solid;border-color:yellow">
<span class='originalcontent'>original content</span>
</div>
</div>
<template id="parentTemplate">
<div id="parentDiv">
<div style="border-style:solid;border-color:green">
<H3 class="shadowheading parentshadowheading">Parent</H3>
<H4>Parent Contents</H4>
<content></content>
</div>
</div>
</template>
<template id="olderChildTemplate">
<div id="olderChildDiv">
<div style="border-style:solid;border-color:red">
<H3 class="shadowheading oldershadowheading">Older Child</H3>
<H4>Older Child Contents</H4>
<content></content>
</div>
</div>
</template>
<template id="youngerChildTemplate">
<div id="youngerChildDiv">
<div style="border-style:solid;border-color:blue">
<H3 class="shadowheading youngershadowheading">Younger Child</H3>
<div style="border-style:dotted;border-color:blue">
<H4>
Younger Child Contents
</H4>
<content></content>
</div>
<div style="border-style:dashed;border-color:blue">
<H4>Younger Child Shadow</H4>
<shadow></shadow>
</div>
</div>
</div>
</template>
18 changes: 18 additions & 0 deletions testapp/shadow/shadow.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
function ShadowCtrl($scope) {
// This is terrible Angular.js style, do not put DOM manipulation inside
// controllers like this.
var parentShadowRoot = document.querySelector('#innerDiv')
.createShadowRoot();
parentShadowRoot.appendChild(document.querySelector('#parentTemplate')
.content.cloneNode(true));
var olderShadowRoot = parentShadowRoot.querySelector("#parentDiv")
.createShadowRoot();
olderShadowRoot.appendChild(document.querySelector('#olderChildTemplate')
.content.cloneNode(true));
var youngerShadowRoot = parentShadowRoot.querySelector("#parentDiv")
.createShadowRoot();
youngerShadowRoot.appendChild(document.querySelector('#youngerChildTemplate')
.content.cloneNode(true));
}

RepeaterCtrl.$inject = ['$scope'];

0 comments on commit d220ecf

Please sign in to comment.