| // Copyright 2019 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifdef UNSAFE_BUFFERS_BUILD |
| // TODO(crbug.com/40285824): Remove this and convert code to safer constructs. |
| #pragma allow_unsafe_buffers |
| #endif |
| |
| #import <UIKit/UIKit.h> |
| #import <XCTest/XCTest.h> |
| |
| #import "base/test/ios/wait_util.h" |
| #import "build/branding_buildflags.h" |
| #import "ios/chrome/test/earl_grey/chrome_actions.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" |
| #import "net/test/embedded_test_server/embedded_test_server.h" |
| |
| using chrome_test_util::RegularTabGrid; |
| using chrome_test_util::ScrollToTop; |
| using chrome_test_util::TabGridCellAtIndex; |
| |
| const char kPDFPath[] = "/complex_document.pdf"; |
| const char kGreenPDFPath[] = "/green.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. |
| // TODO(crbug.com/435094983): Reenable this test. |
| - (void)testSwitchToAndFromPDF { |
| if ([ChromeEarlGrey isIPhoneIdiom]) { |
| if (!@available(iOS 18, *)) { |
| EARL_GREY_TEST_DISABLED(@"Failing on iPhone Simulator"); |
| } |
| } |
| |
| // 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)]; |
| |
| [ChromeEarlGreyUI openTabGrid]; |
| |
| // 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)]; |
| |
| [ChromeEarlGreyUI openTabGrid]; |
| |
| base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(5)); |
| |
| // Leave the tab grid. |
| [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridDoneButton()] |
| performAction:grey_tap()]; |
| } |
| |
| // Tests the center color of the grid tab showing a PDF. (physical device only) |
| - (void)testCenterColorOfPDFTabGrid { |
| #if TARGET_OS_SIMULATOR |
| EARL_GREY_TEST_SKIPPED(@"The API to take a snapshot is not working correctly " |
| @"and it becomes black on simulator."); |
| #endif |
| |
| GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); |
| |
| // Load a page, then a PDF. |
| [ChromeEarlGrey loadURL:self.testServer->GetURL(kGreenPDFPath)]; |
| |
| // Open more than 6 pages to scroll down/up in a tab grid. |
| for (int i = 0; i < 10; i++) { |
| [ChromeEarlGreyUI openNewTab]; |
| [ChromeEarlGrey loadURL:self.testServer->GetURL("/echo")]; |
| } |
| |
| // Open a tab grid and then scroll up to make a tab grid cell recycled and |
| // re-created. |
| [ChromeEarlGreyUI openTabGrid]; |
| [[EarlGrey selectElementWithMatcher:RegularTabGrid()] |
| performAction:ScrollToTop()]; |
| |
| // Take a snapshot of the tab grid showing a PDF. |
| EDORemoteVariable<UIImage*>* tabGridSnapshot = |
| [[EDORemoteVariable alloc] init]; |
| [ChromeEarlGrey waitForUIElementToAppearWithMatcher:TabGridCellAtIndex(0)]; |
| [[EarlGrey selectElementWithMatcher:TabGridCellAtIndex(0)] |
| performAction:grey_snapshot(tabGridSnapshot)]; |
| |
| // Get a color of the center position in a tab grid. |
| CGFloat red = 0.0, green = 0.0, blue = 0.0, alpha = 0.0; |
| [self getCenterColor:tabGridSnapshot.object |
| red:&red |
| green:&green |
| blue:&blue |
| alpha:&alpha]; |
| |
| // The values may not be exactly 0.0 or 1.0 due to the image compression. The |
| // test allows more flexible values. |
| GREYAssert( |
| red < 0.1, |
| @"A red value of the center color in a tab grid should be close to 0."); |
| GREYAssert( |
| green > 0.9, |
| @"A green value of the center color in a tab grid should be close to 1."); |
| GREYAssert( |
| blue < 0.1, |
| @"A blue value of the center color in a tab grid should be close to 0."); |
| GREYAssert( |
| alpha > 0.9, |
| @"A alpha value of the center color in a tab grid should be close to 1."); |
| } |
| |
| #pragma mark - Helper methods |
| |
| - (void)getCenterColor:(UIImage*)image |
| red:(CGFloat*)red |
| green:(CGFloat*)green |
| blue:(CGFloat*)blue |
| alpha:(CGFloat*)alpha { |
| CGImageRef imageRef = [image CGImage]; |
| |
| NSUInteger width = CGImageGetWidth(imageRef); |
| NSUInteger height = CGImageGetHeight(imageRef); |
| NSUInteger x = width / 2; |
| NSUInteger y = height / 2; |
| |
| CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); |
| unsigned char* data = |
| (unsigned char*)calloc(height * width * 4, sizeof(unsigned char)); |
| NSUInteger bytesPerPixel = 4; |
| NSUInteger bytesPerRow = bytesPerPixel * width; |
| NSUInteger bitsPerComponent = 8; |
| CGContextRef context = |
| CGBitmapContextCreate(data, width, height, bitsPerComponent, bytesPerRow, |
| colorSpace, kCGImageAlphaPremultipliedLast); |
| CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef); |
| |
| NSUInteger index = (bytesPerRow * y) + x * bytesPerPixel; |
| *red = ((CGFloat)data[index]) / 255.0f; |
| *green = ((CGFloat)data[index + 1]) / 255.0f; |
| *blue = ((CGFloat)data[index + 2]) / 255.0f; |
| *alpha = ((CGFloat)data[index + 3]) / 255.0f; |
| |
| CGColorSpaceRelease(colorSpace); |
| CGContextRelease(context); |
| free(data); |
| } |
| |
| @end |