1
- describe ( 'axe.utils.getXpath' , function ( ) {
1
+ describe ( 'axe.utils.getXpath' , ( ) => {
2
2
'use strict' ;
3
3
4
- var fixture = document . getElementById ( 'fixture' ) ;
4
+ const fixture = document . getElementById ( 'fixture' ) ;
5
5
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
+ }
9
16
10
- it ( 'should be a function' , function ( ) {
17
+ it ( 'should be a function' , ( ) => {
11
18
assert . isFunction ( axe . utils . getXpath ) ;
12
19
} ) ;
13
20
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' ) ;
16
23
fixture . appendChild ( node ) ;
17
24
18
- var sel = axe . utils . getXpath ( node ) ;
25
+ const sel = axe . utils . getXpath ( node ) ;
19
26
20
- assert . equal ( sel , "/div[@id='fixture']/div" ) ;
27
+ assert . equal ( sel , "//div[@id='fixture']/div" ) ;
28
+ assert . equal ( node , getElementByXPath ( sel ) ) ;
21
29
} ) ;
22
30
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' ) ;
25
33
node . id = 'monkeys#are.animals\\ok' ;
26
34
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 ) ) ;
31
41
} ) ;
32
42
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' ) ;
35
45
node . id = 'monkeys' ;
36
46
fixture . appendChild ( node ) ;
37
47
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 ) ) ;
40
70
} ) ;
41
71
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' ) ;
44
74
node . id = 'monkeys' ;
45
75
fixture . appendChild ( node ) ;
46
76
47
77
node = document . createElement ( 'div' ) ;
48
78
node . id = 'monkeys' ;
49
79
fixture . appendChild ( node ) ;
50
80
51
- var sel = axe . utils . getXpath ( node ) ;
81
+ const sel = axe . utils . getXpath ( node ) ;
52
82
53
- assert . equal ( sel , "/div[@id='fixture']/div[2]" ) ;
83
+ assert . equal ( sel , "//div[@id='fixture']/div[2]" ) ;
84
+ assert . equal ( node , getElementByXPath ( sel ) ) ;
54
85
} ) ;
55
86
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 ;
58
89
node = document . createElement ( 'span' ) ;
59
90
fixture . appendChild ( node ) ;
60
91
@@ -74,26 +105,30 @@ describe('axe.utils.getXpath', function () {
74
105
node = document . createElement ( 'span' ) ;
75
106
fixture . appendChild ( node ) ;
76
107
77
- var sel = axe . utils . getXpath ( target ) ;
108
+ const sel = axe . utils . getXpath ( target ) ;
78
109
79
- assert . equal ( sel , "/div[@id='fixture']/div[2]" ) ;
110
+ assert . equal ( sel , "//div[@id='fixture']/div[2]" ) ;
111
+ assert . equal ( target , getElementByXPath ( sel ) ) ;
80
112
} ) ;
81
113
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 ) ;
84
116
assert . equal ( sel , '/html' ) ;
117
+ assert . equal ( document . documentElement , getElementByXPath ( sel ) ) ;
85
118
} ) ;
86
119
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 ) ;
89
122
assert . equal ( sel , '/html/body' ) ;
123
+ assert . equal ( document . body , getElementByXPath ( sel ) ) ;
90
124
} ) ;
91
125
92
126
it ( 'should work on namespaced elements' , function ( ) {
93
127
fixture . innerHTML = '<hx:include>Hello</hx:include>' ;
94
128
var node = fixture . firstChild ;
95
129
var sel = axe . utils . getXpath ( node ) ;
96
130
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
98
133
} ) ;
99
134
} ) ;
0 commit comments