|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 * http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 "use strict"; |
|
5 |
|
6 /** |
|
7 * Ensure that starting a load invalidates shistory. |
|
8 */ |
|
9 add_task(function test_load_start() { |
|
10 // Create a new tab. |
|
11 let tab = gBrowser.addTab("about:blank"); |
|
12 let browser = tab.linkedBrowser; |
|
13 yield promiseBrowserLoaded(browser); |
|
14 |
|
15 // Load a new URI but remove the tab before it has finished loading. |
|
16 browser.loadURI("about:mozilla"); |
|
17 yield promiseContentMessage(browser, "ss-test:onFrameTreeReset"); |
|
18 gBrowser.removeTab(tab); |
|
19 |
|
20 // Undo close the tab. |
|
21 tab = ss.undoCloseTab(window, 0); |
|
22 browser = tab.linkedBrowser; |
|
23 yield promiseBrowserLoaded(browser); |
|
24 |
|
25 // Check that the correct URL was restored. |
|
26 is(browser.currentURI.spec, "about:mozilla", "url is correct"); |
|
27 |
|
28 // Cleanup. |
|
29 gBrowser.removeTab(tab); |
|
30 }); |
|
31 |
|
32 /** |
|
33 * Ensure that purging shistory invalidates. |
|
34 */ |
|
35 add_task(function test_purge() { |
|
36 // Create a new tab. |
|
37 let tab = gBrowser.addTab("about:mozilla"); |
|
38 let browser = tab.linkedBrowser; |
|
39 yield promiseBrowserLoaded(browser); |
|
40 |
|
41 // Create a second shistory entry. |
|
42 browser.loadURI("about:robots"); |
|
43 yield promiseBrowserLoaded(browser); |
|
44 |
|
45 // Check that we now have two shistory entries. |
|
46 SyncHandlers.get(browser).flush(); |
|
47 let {entries} = JSON.parse(ss.getTabState(tab)); |
|
48 is(entries.length, 2, "there are two shistory entries"); |
|
49 |
|
50 // Purge session history. |
|
51 yield sendMessage(browser, "ss-test:purgeSessionHistory"); |
|
52 |
|
53 // Check that we are left with a single shistory entry. |
|
54 SyncHandlers.get(browser).flush(); |
|
55 let {entries} = JSON.parse(ss.getTabState(tab)); |
|
56 is(entries.length, 1, "there is one shistory entry"); |
|
57 |
|
58 // Cleanup. |
|
59 gBrowser.removeTab(tab); |
|
60 }); |
|
61 |
|
62 /** |
|
63 * Ensure that anchor navigation invalidates shistory. |
|
64 */ |
|
65 add_task(function test_hashchange() { |
|
66 const URL = "data:text/html;charset=utf-8,<a id=a href=%23>clickme</a>"; |
|
67 |
|
68 // Create a new tab. |
|
69 let tab = gBrowser.addTab(URL); |
|
70 let browser = tab.linkedBrowser; |
|
71 yield promiseBrowserLoaded(browser); |
|
72 |
|
73 // Check that we start with a single shistory entry. |
|
74 SyncHandlers.get(browser).flush(); |
|
75 let {entries} = JSON.parse(ss.getTabState(tab)); |
|
76 is(entries.length, 1, "there is one shistory entry"); |
|
77 |
|
78 // Click the link and wait for a hashchange event. |
|
79 browser.messageManager.sendAsyncMessage("ss-test:click", {id: "a"}); |
|
80 yield promiseContentMessage(browser, "ss-test:hashchange"); |
|
81 |
|
82 // Check that we now have two shistory entries. |
|
83 SyncHandlers.get(browser).flush(); |
|
84 let {entries} = JSON.parse(ss.getTabState(tab)); |
|
85 is(entries.length, 2, "there are two shistory entries"); |
|
86 |
|
87 // Cleanup. |
|
88 gBrowser.removeTab(tab); |
|
89 }); |
|
90 |
|
91 /** |
|
92 * Ensure that loading pages from the bfcache invalidates shistory. |
|
93 */ |
|
94 add_task(function test_pageshow() { |
|
95 const URL = "data:text/html;charset=utf-8,<h1>first</h1>"; |
|
96 const URL2 = "data:text/html;charset=utf-8,<h1>second</h1>"; |
|
97 |
|
98 // Create a new tab. |
|
99 let tab = gBrowser.addTab(URL); |
|
100 let browser = tab.linkedBrowser; |
|
101 yield promiseBrowserLoaded(browser); |
|
102 |
|
103 // Create a second shistory entry. |
|
104 browser.loadURI(URL2); |
|
105 yield promiseBrowserLoaded(browser); |
|
106 |
|
107 // Go back to the previous url which is loaded from the bfcache. |
|
108 browser.goBack(); |
|
109 yield promiseContentMessage(browser, "ss-test:onFrameTreeCollected"); |
|
110 is(browser.currentURI.spec, URL, "correct url after going back"); |
|
111 |
|
112 // Check that loading from bfcache did invalidate shistory. |
|
113 SyncHandlers.get(browser).flush(); |
|
114 let {index} = JSON.parse(ss.getTabState(tab)); |
|
115 is(index, 1, "first history entry is selected"); |
|
116 |
|
117 // Cleanup. |
|
118 gBrowser.removeTab(tab); |
|
119 }); |
|
120 |
|
121 /** |
|
122 * Ensure that subframe navigation invalidates shistory. |
|
123 */ |
|
124 add_task(function test_subframes() { |
|
125 const URL = "data:text/html;charset=utf-8," + |
|
126 "<iframe src=http%3A//example.com/ name=t></iframe>" + |
|
127 "<a id=a1 href=http%3A//example.com/1 target=t>clickme</a>" + |
|
128 "<a id=a2 href=http%3A//example.com/%23 target=t>clickme</a>"; |
|
129 |
|
130 // Create a new tab. |
|
131 let tab = gBrowser.addTab(URL); |
|
132 let browser = tab.linkedBrowser; |
|
133 yield promiseBrowserLoaded(browser); |
|
134 |
|
135 // Check that we have a single shistory entry. |
|
136 SyncHandlers.get(browser).flush(); |
|
137 let {entries} = JSON.parse(ss.getTabState(tab)); |
|
138 is(entries.length, 1, "there is one shistory entry"); |
|
139 is(entries[0].children.length, 1, "the entry has one child"); |
|
140 |
|
141 // Navigate the subframe. |
|
142 browser.messageManager.sendAsyncMessage("ss-test:click", {id: "a1"}); |
|
143 yield promiseBrowserLoaded(browser, false /* don't ignore subframes */); |
|
144 |
|
145 // Check shistory. |
|
146 SyncHandlers.get(browser).flush(); |
|
147 let {entries} = JSON.parse(ss.getTabState(tab)); |
|
148 is(entries.length, 2, "there now are two shistory entries"); |
|
149 is(entries[1].children.length, 1, "the second entry has one child"); |
|
150 |
|
151 // Go back in history. |
|
152 browser.goBack(); |
|
153 yield promiseBrowserLoaded(browser, false /* don't ignore subframes */); |
|
154 |
|
155 // Navigate the subframe again. |
|
156 browser.messageManager.sendAsyncMessage("ss-test:click", {id: "a2"}); |
|
157 yield promiseContentMessage(browser, "ss-test:hashchange"); |
|
158 |
|
159 // Check shistory. |
|
160 SyncHandlers.get(browser).flush(); |
|
161 let {entries} = JSON.parse(ss.getTabState(tab)); |
|
162 is(entries.length, 2, "there now are two shistory entries"); |
|
163 is(entries[1].children.length, 1, "the second entry has one child"); |
|
164 |
|
165 // Cleanup. |
|
166 gBrowser.removeTab(tab); |
|
167 }); |
|
168 |
|
169 /** |
|
170 * Ensure that navigating from an about page invalidates shistory. |
|
171 */ |
|
172 add_task(function test_about_page_navigate() { |
|
173 // Create a new tab. |
|
174 let tab = gBrowser.addTab("about:blank"); |
|
175 let browser = tab.linkedBrowser; |
|
176 yield promiseBrowserLoaded(browser); |
|
177 |
|
178 // Check that we have a single shistory entry. |
|
179 SyncHandlers.get(browser).flush(); |
|
180 let {entries} = JSON.parse(ss.getTabState(tab)); |
|
181 is(entries.length, 1, "there is one shistory entry"); |
|
182 is(entries[0].url, "about:blank", "url is correct"); |
|
183 |
|
184 browser.loadURI("about:robots"); |
|
185 yield promiseBrowserLoaded(browser); |
|
186 |
|
187 // Check that we have changed the history entry. |
|
188 SyncHandlers.get(browser).flush(); |
|
189 let {entries} = JSON.parse(ss.getTabState(tab)); |
|
190 is(entries.length, 1, "there is one shistory entry"); |
|
191 is(entries[0].url, "about:robots", "url is correct"); |
|
192 |
|
193 // Cleanup. |
|
194 gBrowser.removeTab(tab); |
|
195 }); |
|
196 |
|
197 /** |
|
198 * Ensure that history.pushState and history.replaceState invalidate shistory. |
|
199 */ |
|
200 add_task(function test_pushstate_replacestate() { |
|
201 // Create a new tab. |
|
202 let tab = gBrowser.addTab("http://example.com/1"); |
|
203 let browser = tab.linkedBrowser; |
|
204 yield promiseBrowserLoaded(browser); |
|
205 |
|
206 // Check that we have a single shistory entry. |
|
207 SyncHandlers.get(browser).flush(); |
|
208 let {entries} = JSON.parse(ss.getTabState(tab)); |
|
209 is(entries.length, 1, "there is one shistory entry"); |
|
210 is(entries[0].url, "http://example.com/1", "url is correct"); |
|
211 |
|
212 browser.messageManager. |
|
213 sendAsyncMessage("ss-test:historyPushState", {url: 'test-entry/'}); |
|
214 yield promiseContentMessage(browser, "ss-test:historyPushState"); |
|
215 |
|
216 // Check that we have added the history entry. |
|
217 SyncHandlers.get(browser).flush(); |
|
218 let {entries} = JSON.parse(ss.getTabState(tab)); |
|
219 is(entries.length, 2, "there is another shistory entry"); |
|
220 is(entries[1].url, "http://example.com/test-entry/", "url is correct"); |
|
221 |
|
222 // Disabled until replaceState invalidation is supported. See Bug 967028. |
|
223 browser.messageManager. |
|
224 sendAsyncMessage("ss-test:historyReplaceState", {url: 'test-entry2/'}); |
|
225 yield promiseContentMessage(browser, "ss-test:historyReplaceState"); |
|
226 |
|
227 // Check that we have modified the history entry. |
|
228 SyncHandlers.get(browser).flush(); |
|
229 let {entries} = JSON.parse(ss.getTabState(tab)); |
|
230 is(entries.length, 2, "there is still two shistory entries"); |
|
231 is(entries[1].url, "http://example.com/test-entry/test-entry2/", "url is correct"); |
|
232 |
|
233 // Cleanup. |
|
234 gBrowser.removeTab(tab); |
|
235 }); |