1// Copyright 2018 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. 4 5#import "ios/web/public/test/web_test_with_web_state.h" 6 7#include "base/ios/ios_util.h" 8#import "ios/web/public/js_messaging/web_frame.h" 9#import "ios/web/public/js_messaging/web_frames_manager.h" 10#import "ios/web/public/web_state.h" 11#include "ios/web/public/web_state_observer.h" 12#include "testing/gmock/include/gmock/gmock.h" 13 14#if !defined(__has_feature) || !__has_feature(objc_arc) 15#error "This file requires ARC support." 16#endif 17 18using testing::Truly; 19 20namespace { 21 22// Mocks WebStateObserver navigation callbacks. 23class WebStateObserverMock : public web::WebStateObserver { 24 public: 25 WebStateObserverMock() = default; 26 27 MOCK_METHOD2(WebFrameDidBecomeAvailable, 28 void(web::WebState*, web::WebFrame*)); 29 MOCK_METHOD2(WebFrameWillBecomeUnavailable, 30 void(web::WebState*, web::WebFrame*)); 31 void WebStateDestroyed(web::WebState* web_state) override { NOTREACHED(); } 32 33 private: 34 DISALLOW_COPY_AND_ASSIGN(WebStateObserverMock); 35}; 36 37// A predicate that returns true if |frame| is a main frame. 38bool IsMainFrame(web::WebFrame* frame) { 39 return frame->IsMainFrame(); 40} 41 42// Verifies that the web frame passed to the observer is the main frame. 43ACTION_P(VerifyMainWebFrame, web_state) { 44 EXPECT_EQ(web_state, arg0); 45 EXPECT_EQ(web_state->GetWebFramesManager()->GetMainWebFrame(), arg1); 46} 47 48// Verifies that the web frame passed to the observer is a child frame. 49ACTION_P(VerifyChildWebFrame, web_state) { 50 EXPECT_EQ(web_state, arg0); 51 52 web::WebFramesManager* manager = web_state->GetWebFramesManager(); 53 auto frames = manager->GetAllWebFrames(); 54 EXPECT_TRUE(frames.end() != std::find(frames.begin(), frames.end(), arg1)); 55 EXPECT_NE(manager->GetMainWebFrame(), arg1); 56} 57} 58 59namespace web { 60 61using WebFrameWebStateObserverInttest = WebTestWithWebState; 62 63// Web frame events should be registered on HTTP navigation. 64TEST_F(WebFrameWebStateObserverInttest, SingleWebFrameHTTP) { 65 testing::StrictMock<WebStateObserverMock> observer; 66 web_state()->AddObserver(&observer); 67 EXPECT_CALL(observer, WebFrameDidBecomeAvailable(web_state(), testing::_)) 68 .WillOnce(VerifyMainWebFrame(web_state())); 69 LoadHtml(@"<p></p>", GURL("http://testurl1")); 70 EXPECT_CALL(observer, WebFrameDidBecomeAvailable(web_state(), testing::_)) 71 .WillOnce(VerifyMainWebFrame(web_state())); 72 EXPECT_CALL(observer, WebFrameWillBecomeUnavailable(web_state(), testing::_)) 73 .WillOnce(VerifyMainWebFrame(web_state())); 74 LoadHtml(@"<p></p>", GURL("http://testurl2")); 75 web_state()->RemoveObserver(&observer); 76} 77 78// Web frame events should be registered on HTTPS navigation. 79TEST_F(WebFrameWebStateObserverInttest, SingleWebFrameHTTPS) { 80 testing::StrictMock<WebStateObserverMock> observer; 81 web_state()->AddObserver(&observer); 82 EXPECT_CALL(observer, WebFrameDidBecomeAvailable(web_state(), testing::_)) 83 .WillOnce(VerifyMainWebFrame(web_state())); 84 LoadHtml(@"<p></p>", GURL("https://testurl1")); 85 EXPECT_CALL(observer, WebFrameDidBecomeAvailable(web_state(), testing::_)) 86 .WillOnce(VerifyMainWebFrame(web_state())); 87 EXPECT_CALL(observer, WebFrameWillBecomeUnavailable(web_state(), testing::_)) 88 .WillOnce(VerifyMainWebFrame(web_state())); 89 LoadHtml(@"<p></p>", GURL("https://testurl2")); 90 web_state()->RemoveObserver(&observer); 91} 92 93// Web frame event should be registered on HTTPS navigation with iframe. 94TEST_F(WebFrameWebStateObserverInttest, TwoWebFrameHTTPS) { 95 testing::StrictMock<WebStateObserverMock> observer; 96 web_state()->AddObserver(&observer); 97 98 // The order in which the main and child frames become available is not 99 // guaranteed due to the async nature of messaging. The following expectations 100 // use separate matchers to identify main and child frames so that they can 101 // be matched in any order. 102 EXPECT_CALL(observer, 103 WebFrameDidBecomeAvailable(web_state(), Truly(IsMainFrame))) 104 .WillOnce(VerifyMainWebFrame(web_state())); 105 EXPECT_CALL(observer, 106 WebFrameDidBecomeAvailable(web_state(), Not(Truly(IsMainFrame)))) 107 .WillOnce(VerifyChildWebFrame(web_state())); 108 LoadHtml(@"<p><iframe/></p>", GURL("https://testurl1")); 109 110 EXPECT_CALL(observer, 111 WebFrameDidBecomeAvailable(web_state(), Truly(IsMainFrame))) 112 .WillOnce(VerifyMainWebFrame(web_state())); 113 EXPECT_CALL(observer, 114 WebFrameDidBecomeAvailable(web_state(), Not(Truly(IsMainFrame)))) 115 .WillOnce(VerifyChildWebFrame(web_state())); 116 EXPECT_CALL(observer, 117 WebFrameWillBecomeUnavailable(web_state(), Truly(IsMainFrame))) 118 .WillOnce(VerifyMainWebFrame(web_state())); 119 EXPECT_CALL(observer, WebFrameWillBecomeUnavailable(web_state(), 120 Not(Truly(IsMainFrame)))) 121 .WillOnce(VerifyChildWebFrame(web_state())); 122 LoadHtml(@"<p><iframe/></p>", GURL("https://testurl2")); 123 124 web_state()->RemoveObserver(&observer); 125} 126 127} // namespace web 128