1- describe ( 'axe.utils.getXpath' , function ( ) {
1+ describe ( 'axe.utils.getXpath' , ( ) => {
22 'use strict' ;
33
4- var fixture = document . getElementById ( 'fixture' ) ;
4+ const fixture = document . getElementById ( 'fixture' ) ;
55
6- afterEach ( function ( ) {
7- fixture . innerHTML = '' ;
8- } ) ;
6+ // @see https://stackoverflow.com/a/14284815/2124254
7+ function getElementByXPath ( path ) {
8+ return document . evaluate (
9+ path ,
10+ document ,
11+ ( ) => 'http://www.w3.org/1998/Math/MathML' ,
12+ XPathResult . FIRST_ORDERED_NODE_TYPE ,
13+ null
14+ ) . singleNodeValue ;
15+ }
916
10- it ( 'should be a function' , function ( ) {
17+ it ( 'should be a function' , ( ) => {
1118 assert . isFunction ( axe . utils . getXpath ) ;
1219 } ) ;
1320
14- it ( 'should generate an XPath selector' , function ( ) {
15- var node = document . createElement ( 'div' ) ;
21+ it ( 'should generate an XPath selector' , ( ) => {
22+ const node = document . createElement ( 'div' ) ;
1623 fixture . appendChild ( node ) ;
1724
18- var sel = axe . utils . getXpath ( node ) ;
25+ const sel = axe . utils . getXpath ( node ) ;
1926
20- assert . equal ( sel , "/div[@id='fixture']/div" ) ;
27+ assert . equal ( sel , "//div[@id='fixture']/div" ) ;
28+ assert . equal ( node , getElementByXPath ( sel ) ) ;
2129 } ) ;
2230
23- it ( 'should handle special characters' , function ( ) {
24- var node = document . createElement ( 'div' ) ;
31+ it ( 'should handle special characters' , ( ) => {
32+ const node = document . createElement ( 'div' ) ;
2533 node . id = 'monkeys#are.animals\\ok' ;
2634 fixture . appendChild ( node ) ;
27- assert . equal (
28- axe . utils . getXpath ( node ) ,
29- "/div[@id='monkeys#are.animals\\ok']"
30- ) ;
35+
36+ const sel = axe . utils . getXpath ( node ) ;
37+
38+ assert . equal ( sel , "//div[@id='monkeys#are.animals\\ok']" ) ;
39+
40+ assert . equal ( node , getElementByXPath ( sel ) ) ;
3141 } ) ;
3242
33- it ( 'should stop on unique ID' , function ( ) {
34- var node = document . createElement ( 'div' ) ;
43+ it ( 'should stop on unique ID' , ( ) => {
44+ const node = document . createElement ( 'div' ) ;
3545 node . id = 'monkeys' ;
3646 fixture . appendChild ( node ) ;
3747
38- var sel = axe . utils . getXpath ( node ) ;
39- assert . equal ( sel , "/div[@id='monkeys']" ) ;
48+ const sel = axe . utils . getXpath ( node ) ;
49+ assert . equal ( sel , "//div[@id='monkeys']" ) ;
50+ assert . equal ( node , getElementByXPath ( sel ) ) ;
51+ } ) ;
52+
53+ it ( 'should use the nearest unique ID' , ( ) => {
54+ fixture . innerHTML = `
55+ <div id="dogs">
56+ <div>
57+ <div>
58+ <div id="monkeys">
59+ <div></div>
60+ </div>
61+ </div>
62+ </div>
63+ </div>
64+ ` ;
65+ const node = fixture . querySelector ( '#monkeys > div' ) ;
66+
67+ const sel = axe . utils . getXpath ( node ) ;
68+ assert . equal ( sel , "//div[@id='monkeys']/div" ) ;
69+ assert . equal ( node , getElementByXPath ( sel ) ) ;
4070 } ) ;
4171
42- it ( 'should not use ids if they are not unique' , function ( ) {
43- var node = document . createElement ( 'div' ) ;
72+ it ( 'should not use ids if they are not unique' , ( ) => {
73+ let node = document . createElement ( 'div' ) ;
4474 node . id = 'monkeys' ;
4575 fixture . appendChild ( node ) ;
4676
4777 node = document . createElement ( 'div' ) ;
4878 node . id = 'monkeys' ;
4979 fixture . appendChild ( node ) ;
5080
51- var sel = axe . utils . getXpath ( node ) ;
81+ const sel = axe . utils . getXpath ( node ) ;
5282
53- assert . equal ( sel , "/div[@id='fixture']/div[2]" ) ;
83+ assert . equal ( sel , "//div[@id='fixture']/div[2]" ) ;
84+ assert . equal ( node , getElementByXPath ( sel ) ) ;
5485 } ) ;
5586
56- it ( 'should properly calculate number when siblings are of different type' , function ( ) {
57- var node , target ;
87+ it ( 'should properly calculate number when siblings are of different type' , ( ) => {
88+ let node , target ;
5889 node = document . createElement ( 'span' ) ;
5990 fixture . appendChild ( node ) ;
6091
@@ -74,26 +105,30 @@ describe('axe.utils.getXpath', function () {
74105 node = document . createElement ( 'span' ) ;
75106 fixture . appendChild ( node ) ;
76107
77- var sel = axe . utils . getXpath ( target ) ;
108+ const sel = axe . utils . getXpath ( target ) ;
78109
79- assert . equal ( sel , "/div[@id='fixture']/div[2]" ) ;
110+ assert . equal ( sel , "//div[@id='fixture']/div[2]" ) ;
111+ assert . equal ( target , getElementByXPath ( sel ) ) ;
80112 } ) ;
81113
82- it ( 'should work on the documentElement' , function ( ) {
83- var sel = axe . utils . getXpath ( document . documentElement ) ;
114+ it ( 'should work on the documentElement' , ( ) => {
115+ const sel = axe . utils . getXpath ( document . documentElement ) ;
84116 assert . equal ( sel , '/html' ) ;
117+ assert . equal ( document . documentElement , getElementByXPath ( sel ) ) ;
85118 } ) ;
86119
87- it ( 'should work on the body' , function ( ) {
88- var sel = axe . utils . getXpath ( document . body ) ;
120+ it ( 'should work on the body' , ( ) => {
121+ const sel = axe . utils . getXpath ( document . body ) ;
89122 assert . equal ( sel , '/html/body' ) ;
123+ assert . equal ( document . body , getElementByXPath ( sel ) ) ;
90124 } ) ;
91125
92126 it ( 'should work on namespaced elements' , function ( ) {
93127 fixture . innerHTML = '<hx:include>Hello</hx:include>' ;
94128 var node = fixture . firstChild ;
95129 var sel = axe . utils . getXpath ( node ) ;
96130
97- assert . equal ( sel , "/div[@id='fixture']/hx:include" ) ;
131+ assert . equal ( sel , "//div[@id='fixture']/hx:include" ) ;
132+ // couldn't figure out how to use document.evaluate to select an element with namespace
98133 } ) ;
99134} ) ;
0 commit comments