1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Include test fixture.
6 GEN_INCLUDE(['net_internals_test.js']);
12 * Phases of a PrerenderTask.
16 // The task has been created, but not yet started.
19 // We've switched to the prerender tab, but have yet to receive the
20 // resulting onPrerenderInfoChanged event with no prerenders active or in
22 START_PRERENDERING: 0,
23 // We're waiting for the prerender loader to start in a background tab,
24 // as well as the prerendered view to be created. Only visit this state if
25 // |shouldSucceed| is true.
27 // The prerendered view has been created, and we've started the navigation
28 // to it. We're waiting for it to move to the history. We may see the
29 // prerender one or more times in the active list, or it may move straight
30 // to the history. We will not receive any event with both history and
31 // active prerenders empty while in this state, as we only send
32 // notifications when the values change.
37 * Task that tries to prerender a page. The URL is received from the previous
38 * Task. A loader page is opened in a background tab, which triggers the
39 * prerender. |shouldSucceed| indicates whether the prerender is expected to
40 * succeed or not. If it's false, we just wait for the page to fail, possibly
41 * seeing it as active first. If it's true, we navigate to the URL in the
44 * Checks that we see all relevant events, and update the corresponding tables.
45 * In both cases, we exit the test once we see the prerender in the history.
46 * |finalStatus| is the expected status value when the page reaches the
49 * @param {bool} shouldSucceed Whether or not the prerender should succeed.
50 * @param {string} finalStatus The expected value of |final_status|.
51 * @extends {NetInternalsTest.Task}
54 function PrerenderTask(shouldSucceed, finalStatus) {
55 NetInternalsTest.Task.call(this);
57 this.startedSuccessfulPrerender_ = false;
59 this.shouldSucceed_ = shouldSucceed;
60 this.finalStatus_ = finalStatus;
61 this.state_ = STATE.NONE;
64 PrerenderTask.prototype = {
65 __proto__: NetInternalsTest.Task.prototype,
68 * Switches to prerender tab and starts waiting until we receive prerender
69 * info (With no pages prerendering) before starting to prerender.
70 * @param {string} url URL to be prerendered.
72 start: function(url) {
73 assertEquals('string', typeof url);
74 this.state_ = STATE.START_PRERENDERING;
76 g_browser.addPrerenderInfoObserver(this, true);
77 NetInternalsTest.switchToView('prerender');
81 * PrerenderInfoObserver function. Tracks state transitions, checks the
82 * table sizes, and does some sanity checking on received data.
83 * @param {object} prerenderInfo State of prerendering pages.
85 onPrerenderInfoChanged: function(prerenderInfo) {
89 // Verify that prerendering is enabled.
90 assertTrue(prerenderInfo.enabled, 'Prerendering not enabled.');
92 // Check number of rows in both tables.
93 NetInternalsTest.checkTbodyRows(PrerenderView.HISTORY_TABLE_ID,
94 prerenderInfo.history.length);
95 NetInternalsTest.checkTbodyRows(PrerenderView.ACTIVE_TABLE_ID,
96 prerenderInfo.active.length);
98 if (this.state_ == STATE.START_PRERENDERING) {
99 this.startPrerendering_(prerenderInfo);
100 } else if (this.state_ == STATE.NEED_NAVIGATE) {
101 // Can't safely swap in a prerender until the main frame has committed.
102 // Waiting until the load has completed isn't necessary, but it's simpler.
103 if (!prerenderInfo.active[0].is_loaded)
105 this.navigate_(prerenderInfo);
106 } else if (this.state_ == STATE.HISTORY_WAIT) {
107 this.checkDone_(prerenderInfo);
114 * Start by triggering a prerender of |url_| in a background tab.
115 * At this point, we expect no active or historical prerender entries.
116 * @param {Object} prerenderInfo State of prerendering pages.
118 startPrerendering_: function(prerenderInfo) {
119 expectEquals(0, prerenderInfo.active.length);
120 expectEquals(0, prerenderInfo.history.length);
121 if (this.shouldSucceed_) {
122 chrome.send('prerenderPage', [this.url_]);
124 this.state_ = STATE.NEED_NAVIGATE;
126 // If the prerender is going to fail, we can add the prerender link to the
127 // current document, so we will create one less process. Unfortunately,
128 // if the prerender is going to succeed, we have to create a new process
129 // with the prerender link, to avoid the prerender being cancelled due to
130 // a session storage namespace mismatch.
131 var link = document.createElement('link');
132 link.rel = 'prerender';
133 link.href = this.url_;
134 document.head.appendChild(link);
136 this.state_ = STATE.HISTORY_WAIT;
141 * Navigate to the prerendered page in the background tab.
142 * @param {Object} prerenderInfo State of prerendering pages.
144 navigate_: function(prerenderInfo) {
145 expectEquals(0, prerenderInfo.history.length);
146 assertEquals(1, prerenderInfo.active.length);
147 expectEquals(this.url_, prerenderInfo.active[0].url);
148 expectTrue(this.shouldSucceed_);
149 chrome.send('navigateToPrerender', [this.url_]);
150 this.state_ = STATE.HISTORY_WAIT;
154 * We expect to either see the failure url as an active entry, or see it
155 * in the history. In the latter case, the test completes.
156 * @param {Object} prerenderInfo State of prerendering pages.
158 checkDone_: function(prerenderInfo) {
159 // If we see the url as active, continue running the test.
160 if (prerenderInfo.active.length == 1) {
161 expectEquals(this.url_, prerenderInfo.active[0].url);
162 expectEquals(0, prerenderInfo.history.length);
166 // The prerender of |url_| is now in the history.
167 this.checkHistory_(prerenderInfo);
171 * Check if the history is consistent with expectations, and end the test.
172 * @param {Object} prerenderInfo State of prerendering pages.
174 checkHistory_: function(prerenderInfo) {
175 expectEquals(0, prerenderInfo.active.length);
176 assertEquals(1, prerenderInfo.history.length);
177 expectEquals(this.url_, prerenderInfo.history[0].url);
178 expectEquals(this.finalStatus_, prerenderInfo.history[0].final_status);
185 * Prerender a page and navigate to it, once prerendering starts.
187 TEST_F('NetInternalsTest', 'netInternalsPrerenderViewSucceed', function() {
188 var taskQueue = new NetInternalsTest.TaskQueue(true);
190 new NetInternalsTest.GetTestServerURLTask('files/title1.html'));
191 taskQueue.addTask(new PrerenderTask(true, 'Used'));
196 * Prerender a page that is expected to fail.
198 TEST_F('NetInternalsTest', 'netInternalsPrerenderViewFail', function() {
199 var taskQueue = new NetInternalsTest.TaskQueue(true);
201 new NetInternalsTest.GetTestServerURLTask('files/download-test1.lib'));
202 taskQueue.addTask(new PrerenderTask(false, 'Download'));
206 })(); // Anonymous namespace