| <!DOCTYPE html> |
| <html> |
| <head> |
| <meta charset="utf-8" /> |
| <title>Page Visibility API Operation While Changing Tabs</title> |
| <meta name="flags" content="interact" /> |
| <script type="text/javascript" src="/resources/testharness.js"></script> |
| <script type="text/javascript" src="resources/pagevistestharness.js"></script> |
| |
| </head> |
| <body> |
| <h1>Description</h1> |
| <p>This test validates that the page properly becomes hidden and visible due to switching tabs.</p> |
| |
| <h1>Manual Test Steps:</h1> |
| <p> |
| <ol> |
| <li> Ensure this page is the foreground and click the "Start Test"</li> |
| <li> Switch to another tab</li> |
| <li> Return to the current tab containing this test page</li> |
| </ol> |
| Note: This test will automatically timeout and fail if not completed within 60 seconds. |
| </p> |
| |
| <button onclick="start_test();">Start Test</button> |
| |
| <div id="log"></div> |
| |
| <br /> |
| IFrame with default style: |
| <br /> |
| <iframe id="childDocShown" src="resources/blank_page_green.html"> |
| iframes unsupported |
| </iframe> |
| <hr /> |
| IFrame with "display:none" style: |
| <br /> |
| <iframe id="childDocHidden" src="resources/blank_page_green.html" style="display:none"> |
| iframes unsupported |
| </iframe> |
| |
| <script type="text/javascript" > |
| var child_doc_shown = null; |
| var child_doc_hidden = null; |
| var transition_mode; |
| var manual_test = null; |
| |
| var expected_notification_count = 2; |
| var notification_count = new Array(); |
| var page_docs = new Array(); |
| var notification_handlers = new Array(); |
| var two_notifications = false; |
| |
| var PAGE_HIDDEN_VAL = "hidden"; |
| var PAGE_VISIBLE_VAL = "visible"; |
| |
| setup({ explicit_done: true }); |
| |
| function test_transition_init() |
| { |
| child_doc_shown = document.getElementById("childDocShown").contentDocument; |
| child_doc_hidden = document.getElementById("childDocHidden").contentDocument; |
| |
| // fill in data for page documents |
| page_docs.push([document, "document"]); |
| page_docs.push([child_doc_shown, "document.getElementById(\"childDocShown\").contentDocument"]); |
| page_docs.push([child_doc_hidden, "document.getElementById(\"childDocHidden\").contentDocument"]); |
| |
| notification_handlers[0] = function(){ VerifyNotification(0); }; |
| notification_handlers[1] = function(){ VerifyNotification(1); }; |
| notification_handlers[2] = function(){ VerifyNotification(2); }; |
| |
| for (var i in page_docs) |
| { |
| notification_count[i] = 0; |
| page_docs[i][0].addEventListener("visibilitychange", notification_handlers[i]); |
| } |
| |
| test_true(!document.hidden, "Page is visible on load."); |
| test_true((!child_doc_shown.hidden) && (!child_doc_hidden.hidden), |
| "All IFrame child documents are visible on load."); |
| |
| document.addEventListener("visibilitychange", notification_handlers[0]); |
| document.addEventListener("visibilitychange", VerifyTwoNotifications); |
| |
| manual_test = AddManual("Browser tab switch has occurred."); |
| } |
| |
| function VerifyNotification(doc_index) |
| { |
| doc = page_docs[doc_index][0]; |
| docName = page_docs[doc_index][1]; |
| |
| notification_count[doc_index]++; |
| switch (notification_count[doc_index]) |
| { |
| case 1: |
| // First step, check page visibility after tab deselection / minimization. |
| // hidden should change to true; visibilityState should change to "hidden" |
| test_true(doc.hidden, docName + ".hidden == true (after tab switch)"); |
| test_true(doc.visibilityState == PAGE_HIDDEN_VAL, |
| docName + ".visibilityState == \"hidden\" (after tab switch)"); |
| |
| break; |
| |
| case 2: |
| //Second step, check page visibility after tab reselection / maximization / restoration. |
| // hidden should change to false; visibilityState should change to "visible" |
| test_true(!doc.hidden, |
| docName + ".hidden == false (after return to original tab)"); |
| test_true(doc.visibilityState == PAGE_VISIBLE_VAL, |
| docName + ".visibilityState == \"visible\" (after return to original tab)"); |
| |
| // perform tests specific to the main document |
| if (doc == document) |
| { |
| //Verify that a second registration to a different callback also occurred |
| test_true(two_notifications, "Two registrations (different callbacks) occurred."); |
| |
| //Verify that a second registration to the same callback did not occur |
| test_equals(notification_count[doc_index], |
| expected_notification_count, |
| "Two registrations (same callback) did not occur."); |
| |
| // pass the manual item associated with these tests |
| AddManualResult(manual_test, true); |
| |
| document.removeEventListener("visibilitychange", VerifyTwoNotifications); |
| |
| // schedule the rollup |
| setTimeout(VerifyAllNotifications, 200); |
| } |
| |
| //Remove all event listeners and verify that the event does not fire |
| doc.removeEventListener("visibilitychange", notification_handlers[doc_index]); |
| break; |
| case 3: |
| //This step should not have occurred since the event handlers were cleared |
| test_true(false, "Event did not fire when event listener is removed."); |
| |
| //On final step, schedule the rollup |
| setTimeout(done, 2000); |
| break; |
| |
| default: |
| break; |
| } |
| } |
| |
| function VerifyAllNotifications() |
| { |
| //On final step, schedule the rollup |
| setTimeout(done, 1000); |
| } |
| |
| function VerifyTwoNotifications() |
| { |
| //This is a duplicate registration on visibilitychange and |
| //should never get fired. Check that duplicate_notification |
| //is false to verify that this never occurred. |
| two_notifications = true; |
| } |
| |
| // Manual Test helper functions |
| function AddManual(test) |
| { |
| // add asynchronous test for manual tests |
| return async_test(test); |
| } |
| |
| function AddManualResult(oManualTest, passState) |
| { |
| // add assertion to manual test for the pass state |
| oManualTest.step(function() {assert_true(passState)}); |
| |
| // end manual test |
| oManualTest.done(); |
| } |
| |
| function start_test() |
| { |
| test_transition_init(); |
| } |
| </script> |
| </body> |
| </html> |