Commit 3a54efae authored by Mark Cogan's avatar Mark Cogan Committed by Commit Bot

[iOS] Regression tests for PDF snapshot crashes.

This CL adds regression tests for some of the PDF snapshot bugs fixed in
prior CLs (see http://crbug/981893). Specifically tests are added for:

- Switching back and forth quickly between a complex PDF and a regular
  tab.

- Switching back and forth quickly between two PDF tabs.

- Opening a PDF and then entering the tab grid and waiting ~5 seconds.

A known-crashing PDF (from www.irs.gov) is added to the test data for
these tests.

Since there's no good single component that "owns" these tests, this CL
creates a ui/integration_tests directory.

Since this test needs a way to locate the toolbar for swiping to change
tabs, this CL adds a utility matcher for that.

TEST=I verified that the crashes fixed before could be retriggered by at
least one of these tests. The root cause of the crash was that WebKit
was calling snapshotting callbacks more than once, and the implementation
of the callback was a OnceCallback. The fix was to change this to a
RepeatingCallback. I verified that these tests would have found this
regression by CHECKing the second time the callback was called.

Bug: 993395
Change-Id: Iea130d4ed82017096ad3420161fb59a224d128d0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1768707
Commit-Queue: Mark Cogan <marq@chromium.org>
Reviewed-by: default avatarGauthier Ambard <gambard@chromium.org>
Cr-Commit-Position: refs/heads/master@{#692039}
parent ef8ea43c
# Copyright 2019 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.
source_set("eg2_tests") {
defines = [ "CHROME_EARL_GREY_2" ]
configs += [
"//build/config/compiler:enable_arc",
"//build/config/ios:xctest_config",
]
testonly = true
sources = [
"pdf_egtest.mm",
]
deps = [
"//ios/chrome/test/earl_grey:eg_test_support+eg2",
"//ios/testing/earl_grey:eg_test_support+eg2",
"//ios/third_party/earl_grey2:test_lib",
"//ui/base",
]
libs = [
"UIKit.framework",
"XCTest.framework",
]
}
// Copyright 2019 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 <UIKit/UIKit.h>
#import <XCTest/XCTest.h>
#import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
#import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
#import "ios/chrome/test/earl_grey/chrome_matchers.h"
#import "ios/chrome/test/earl_grey/chrome_test_case.h"
#import "ios/testing/earl_grey/earl_grey_test.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
const char kPDFPath[] = "/complex_document.pdf";
@interface PDFTestCase : ChromeTestCase
@end
@implementation PDFTestCase
// Regression test for crbug/981893. Repro steps: open a PDF in a new
// tab, switch back and forth betweeen the new tab and the old one by
// swiping in the toolbar. The regression is a crash.
- (void)testSwitchToAndFromPDF {
// Compact width only.
if (![ChromeEarlGrey isCompactWidth]) {
EARL_GREY_TEST_DISABLED(@"Disabled on iPad -- depends on swiping in the "
@"toolbar to change tabs, which is a compact-"
@"only feature.");
}
GREYAssertTrue(self.testServer->Start(), @"Test server failed to start.");
// Load the first page.
[ChromeEarlGrey loadURL:self.testServer->GetURL("/echo")];
[ChromeEarlGrey waitForWebStateContainingText:"Echo"];
// Open a new Tab to have a tab to switch to.
[ChromeEarlGreyUI openNewTab];
[ChromeEarlGrey loadURL:self.testServer->GetURL(kPDFPath)];
id<GREYMatcher> toolbar = chrome_test_util::PrimaryToolbar();
// Swipe to the first page.
[[EarlGrey selectElementWithMatcher:toolbar]
performAction:grey_swipeSlowInDirection(kGREYDirectionRight)];
[ChromeEarlGrey waitForWebStateContainingText:"Echo"];
// Swipe back and forth a few times. If this crashes, there may be a new
// problem with how WKWebView snapshots PDFs.
for (int i = 0; i < 3; i++) {
[[EarlGrey selectElementWithMatcher:toolbar]
performAction:grey_swipeFastInDirection(kGREYDirectionLeft)];
[[EarlGrey selectElementWithMatcher:toolbar]
performAction:grey_swipeFastInDirection(kGREYDirectionRight)];
}
[ChromeEarlGrey waitForWebStateContainingText:"Echo"];
}
// Regression test for crbug/981893. Repro steps: open PDFs in two tabs.
// Enter and leave the tab grid. Swipe back and forth repeatedly between
// the two tabs in the toolbar. The regressiom is a crash anywhere in this
// process.
- (void)testSwitchBetweenPDFs {
// Compact width only.
if (![ChromeEarlGrey isCompactWidth]) {
EARL_GREY_TEST_DISABLED(@"Disabled on iPad -- depends on swiping in the "
@"toolbar to change tabs, which is a compact-"
@"only feature.");
}
GREYAssertTrue(self.testServer->Start(), @"Test server failed to start.");
// Load two PDFs in different tabs.
[ChromeEarlGrey loadURL:self.testServer->GetURL(kPDFPath)];
[ChromeEarlGreyUI openNewTab];
[ChromeEarlGrey loadURL:self.testServer->GetURL(kPDFPath)];
// Enter the tab grid.
[[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
performAction:grey_tap()];
// Leave the tab grid.
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridDoneButton()]
performAction:grey_tap()];
id<GREYMatcher> toolbar = chrome_test_util::PrimaryToolbar();
// Swipe back and forth a few times. If this crashes, there may be a new
// problem with how WKWebView snapshots PDFs.
for (int i = 0; i < 3; i++) {
[[EarlGrey selectElementWithMatcher:toolbar]
performAction:grey_swipeFastInDirection(kGREYDirectionLeft)];
[[EarlGrey selectElementWithMatcher:toolbar]
performAction:grey_swipeFastInDirection(kGREYDirectionRight)];
}
}
// Regression test for crbug/981893. Repro steps: Open a tab, then navigate
// to a PDF in that tab. Enter the tab grid. Wait five seconds. Exit the
// tab switcher. The regression is a crash anywhere in this process.
- (void)testPDFIntoTabGridAndWait {
GREYAssertTrue(self.testServer->Start(), @"Test server failed to start.");
// Load a page, then a PDF
[ChromeEarlGrey loadURL:self.testServer->GetURL("/echo")];
[ChromeEarlGrey loadURL:self.testServer->GetURL(kPDFPath)];
// Enter the tab grid.
[[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
performAction:grey_tap()];
// Wait five seconds.
XCTestExpectation* neverFulfilled =
[[XCTestExpectation alloc] initWithDescription:@"Wait"];
XCTWaiterResult result = [XCTWaiter waitForExpectations:@[ neverFulfilled ]
timeout:5.0];
GREYAssertTrue(result == XCTWaiterResultTimedOut,
@"Was not able to complete wait in tab grid with a PDF tab.");
// Leave the tab grid.
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridDoneButton()]
performAction:grey_tap()];
}
@end
......@@ -255,6 +255,7 @@ source_set("test_support") {
"//ios/chrome/browser/ui/tab_grid:tab_grid_ui_constants",
"//ios/chrome/browser/ui/tab_grid/grid:grid_ui_constants",
"//ios/chrome/browser/ui/table_view/cells",
"//ios/chrome/browser/ui/toolbar:toolbar_ui",
"//ios/chrome/browser/ui/toolbar/buttons",
"//ios/chrome/browser/ui/toolbar/keyboard_assist",
"//ios/chrome/browser/ui/toolbar/public",
......@@ -357,6 +358,7 @@ source_set("eg_app_support+eg2") {
"//ios/chrome/browser/ui/static_content",
"//ios/chrome/browser/ui/tab_grid:tab_grid_ui_constants",
"//ios/chrome/browser/ui/tab_grid/grid:grid_ui_constants",
"//ios/chrome/browser/ui/toolbar:toolbar_ui",
"//ios/chrome/browser/ui/toolbar/keyboard_assist",
"//ios/chrome/browser/ui/toolbar/public",
"//ios/chrome/browser/ui/util",
......
......@@ -47,6 +47,9 @@ id<GREYMatcher> HeaderWithAccessibilityLabelId(int message_id);
// accessibility trait UIAccessibilityTraitHeader.
id<GREYMatcher> HeaderWithAccessibilityLabel(NSString* label);
// Returns matcher for the primary toolbar.
id<GREYMatcher> PrimaryToolbar();
// Returns matcher for a cancel button.
id<GREYMatcher> CancelButton();
......
......@@ -55,6 +55,10 @@ id<GREYMatcher> HeaderWithAccessibilityLabel(NSString* label) {
return [ChromeMatchersAppInterface headerWithAccessibilityLabel:label];
}
id<GREYMatcher> PrimaryToolbar() {
return [ChromeMatchersAppInterface primaryToolbar];
}
id<GREYMatcher> CancelButton() {
return [ChromeMatchersAppInterface cancelButton];
}
......
......@@ -49,6 +49,9 @@
// accessibility trait UIAccessibilityTraitHeader.
+ (id<GREYMatcher>)headerWithAccessibilityLabel:(NSString*)label;
// Returns matcher for the primary toolbar.
+ (id<GREYMatcher>)primaryToolbar;
// Returns matcher for a cancel button.
+ (id<GREYMatcher>)cancelButton;
......
......@@ -36,6 +36,7 @@
#import "ios/chrome/browser/ui/tab_grid/grid/grid_constants.h"
#import "ios/chrome/browser/ui/tab_grid/tab_grid_constants.h"
#import "ios/chrome/browser/ui/toolbar/keyboard_assist/toolbar_assistive_keyboard_views_utils.h"
#import "ios/chrome/browser/ui/toolbar/primary_toolbar_view.h"
#import "ios/chrome/browser/ui/toolbar/public/toolbar_constants.h"
#import "ios/chrome/browser/ui/util/ui_util.h"
#import "ios/chrome/browser/ui/util/uikit_ui_util.h"
......@@ -198,6 +199,10 @@ UIView* SubviewWithAccessibilityIdentifier(NSString* accessibility_id,
grey_accessibilityTrait(UIAccessibilityTraitHeader), nil);
}
+ (id<GREYMatcher>)primaryToolbar {
return grey_kindOfClass([PrimaryToolbarView class]);
}
+ (id<GREYMatcher>)cancelButton {
return
[ChromeMatchersAppInterface buttonWithAccessibilityLabelID:(IDS_CANCEL)];
......
......@@ -41,6 +41,7 @@ chrome_ios_eg2_test("ios_chrome_ui_eg2tests_module") {
deps = [
"//ios/chrome/browser/ui/activity_services:eg2_tests",
"//ios/chrome/browser/ui/download:eg2_tests",
"//ios/chrome/browser/ui/integration_tests:eg2_tests",
"//ios/chrome/browser/ui/omnibox/popup:eg2_tests",
"//ios/chrome/browser/ui/omnibox/popup/shortcuts:eg2_tests",
"//ios/chrome/browser/ui/open_in:eg2_tests",
......
......@@ -79,6 +79,7 @@ bundle_data("http_server_bundle_data") {
"data/http_server_files/browsing_prevent_default_test_page.html",
"data/http_server_files/chromium_logo.png",
"data/http_server_files/chromium_logo_page.html",
"data/http_server_files/complex_document.pdf",
"data/http_server_files/console.html",
"data/http_server_files/console_with_iframe.html",
"data/http_server_files/context_menu.html",
......
This diff was suppressed by a .gitattributes entry.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment