blob: 245ccd2d7fb11b8aea122577507f42323f56a0f7 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import <CoreGraphics/CoreGraphics.h>
#import <Foundation/Foundation.h>
#import <XCTest/XCTest.h>
#include "base/strings/string_number_conversions.h"
#include "base/strings/sys_string_conversions.h"
#import "ios/testing/earl_grey/earl_grey_test.h"
#import "ios/web/shell/test/earl_grey/shell_earl_grey.h"
#import "ios/web/shell/test/earl_grey/shell_matchers.h"
#import "ios/web/shell/test/earl_grey/web_shell_test_case.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
namespace {
const char kLongPage1[] = "/ios/testing/data/http_server_files/tall_page.html";
const char kLongPage2[] =
// Test scroll offsets.
const CGFloat kOffset1 = 20.0f;
const CGFloat kOffset2 = 40.0f;
// Waits for the web view scroll view is scrolled to |y_offset|.
void WaitForOffset(CGFloat y_offset) {
CGPoint offset = CGPointMake(0.0, y_offset);
NSString* content_offset_string = NSStringFromCGPoint(offset);
NSString* name =
[NSString stringWithFormat:@"Wait for scroll view to scroll to %@.",
GREYCondition* condition = [GREYCondition
block:^BOOL {
NSError* error = nil;
return (error == nil);
NSString* error_text =
[NSString stringWithFormat:@"Scroll view did not scroll to %@",
GREYAssert([condition waitWithTimeout:10], error_text);
// Loads the long page at |url|, scrolls to the top, and waits for the offset to
// be {0, 0} before returning.
void ScrollLongPageToTop(const GURL& url) {
// Load the page and swipe down.
[ShellEarlGrey loadURL:url];
[[EarlGrey selectElementWithMatcher:web::WebViewScrollView()]
// Waits for the {0, 0} offset.
} // namespace
// Page state test cases for the web shell.
@interface PageStateTestCase : WebShellTestCase {
net::EmbeddedTestServer _server;
@implementation PageStateTestCase
- (void)setUp {
[super setUp];
NSString* bundlePath = [NSBundle bundleForClass:[self class]].resourcePath;
GREYAssert(_server.Start(), @"EmbeddedTestServer failed to start.");
// Tests that page scroll position of a page is restored upon returning to the
// page via the back/forward buttons.
- (void)testScrollPositionRestoring {
// grey_scrollInDirection scrolls incorrect distance on iOS 13.
// TODO( Enable this test on iOS 13.
if (@available(iOS 13, *)) {
// Scroll the first page and verify the offset.
[[EarlGrey selectElementWithMatcher:web::WebViewScrollView()]
performAction:grey_scrollInDirection(kGREYDirectionDown, kOffset1)];
[[EarlGrey selectElementWithMatcher:web::WebViewScrollView()]
assertWithMatcher:grey_scrollViewContentOffset(CGPointMake(0, kOffset1))];
// Scroll the second page and verify the offset.
[[EarlGrey selectElementWithMatcher:web::WebViewScrollView()]
performAction:grey_scrollInDirection(kGREYDirectionDown, kOffset2)];
[[EarlGrey selectElementWithMatcher:web::WebViewScrollView()]
assertWithMatcher:grey_scrollViewContentOffset(CGPointMake(0, kOffset2))];
// Go back and verify that the first page offset has been restored.
[[EarlGrey selectElementWithMatcher:web::BackButton()]
// Go forward and verify that the second page offset has been restored.
[[EarlGrey selectElementWithMatcher:web::ForwardButton()]
// Tests that the content offset of the webview scroll view is {0, 0} after a
// load.
- (void)testZeroContentOffsetAfterLoad {
// Set up the file-based server to load the tall page.
const GURL baseURL = _server.GetURL(kLongPage1);
[ShellEarlGrey loadURL:baseURL];
// Scroll the page and load again to verify that the new page's scroll offset
// is reset to {0, 0}.
const CGFloat kOffsetIncrement = 20.0;
for (NSInteger i = 0; i < 10; ++i) {
// Scroll down the page a bit before re-loading the URL.
CGFloat offset = (i + 1) * kOffsetIncrement;
[[EarlGrey selectElementWithMatcher:web::WebViewScrollView()]
performAction:grey_scrollInDirection(kGREYDirectionDown, offset)];
// Add a query parameter so the next load creates another NavigationItem.
GURL::Replacements replacements;
std::string query_string = base::NumberToString(i);
[ShellEarlGrey loadURL:baseURL.ReplaceComponents(replacements)];
// Wait for the content offset to be set to {0, 0}.