| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import <AVFoundation/AVFoundation.h> | 5 #import <AVFoundation/AVFoundation.h> |
| 6 #import <EarlGrey/EarlGrey.h> | 6 #import <EarlGrey/EarlGrey.h> |
| 7 #import <UIKit/UIKit.h> | 7 #import <UIKit/UIKit.h> |
| 8 | 8 |
| 9 #import "base/mac/scoped_nsobject.h" | 9 #import "base/mac/scoped_nsobject.h" |
| 10 #include "base/strings/sys_string_conversions.h" | 10 #include "base/strings/sys_string_conversions.h" |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 char kTestQueryEditedResponse[] = "Test query edited page"; | 51 char kTestQueryEditedResponse[] = "Test query edited page"; |
| 52 | 52 |
| 53 // The GREYCondition timeout used for calls to waitWithTimeout:pollInterval:. | 53 // The GREYCondition timeout used for calls to waitWithTimeout:pollInterval:. |
| 54 CFTimeInterval kGREYConditionTimeout = 5; | 54 CFTimeInterval kGREYConditionTimeout = 5; |
| 55 // The GREYCondition poll interval used for calls to | 55 // The GREYCondition poll interval used for calls to |
| 56 // waitWithTimeout:pollInterval:. | 56 // waitWithTimeout:pollInterval:. |
| 57 CFTimeInterval kGREYConditionPollInterval = 0.1; | 57 CFTimeInterval kGREYConditionPollInterval = 0.1; |
| 58 | 58 |
| 59 // Returns the GREYMatcher for an element which is visible, interactable, and | 59 // Returns the GREYMatcher for an element which is visible, interactable, and |
| 60 // enabled. | 60 // enabled. |
| 61 id<GREYMatcher> visibleInteractableEnabled() { | 61 id<GREYMatcher> VisibleInteractableEnabled() { |
| 62 return grey_allOf(grey_sufficientlyVisible(), grey_interactable(), | 62 return grey_allOf(grey_sufficientlyVisible(), grey_interactable(), |
| 63 grey_enabled(), nil); | 63 grey_enabled(), nil); |
| 64 } | 64 } |
| 65 | 65 |
| 66 // Returns the GREYMatcher for the button that closes the QR Scanner. | 66 // Returns the GREYMatcher for the button that closes the QR Scanner. |
| 67 id<GREYMatcher> qrScannerCloseButton() { | 67 id<GREYMatcher> QrScannerCloseButton() { |
| 68 return buttonWithAccessibilityLabel( | 68 return ButtonWithAccessibilityLabel( |
| 69 [[ChromeIcon closeIcon] accessibilityLabel]); | 69 [[ChromeIcon closeIcon] accessibilityLabel]); |
| 70 } | 70 } |
| 71 | 71 |
| 72 // Returns the GREYMatcher for the button which indicates that torch is off and | 72 // Returns the GREYMatcher for the button which indicates that torch is off and |
| 73 // which turns on the torch. | 73 // which turns on the torch. |
| 74 id<GREYMatcher> qrScannerTorchOffButton() { | 74 id<GREYMatcher> QrScannerTorchOffButton() { |
| 75 return grey_allOf(grey_accessibilityLabel(l10n_util::GetNSString( | 75 return grey_allOf(grey_accessibilityLabel(l10n_util::GetNSString( |
| 76 IDS_IOS_QR_SCANNER_TORCH_BUTTON_ACCESSIBILITY_LABEL)), | 76 IDS_IOS_QR_SCANNER_TORCH_BUTTON_ACCESSIBILITY_LABEL)), |
| 77 grey_accessibilityValue(l10n_util::GetNSString( | 77 grey_accessibilityValue(l10n_util::GetNSString( |
| 78 IDS_IOS_QR_SCANNER_TORCH_OFF_ACCESSIBILITY_VALUE)), | 78 IDS_IOS_QR_SCANNER_TORCH_OFF_ACCESSIBILITY_VALUE)), |
| 79 grey_accessibilityTrait(UIAccessibilityTraitButton), nil); | 79 grey_accessibilityTrait(UIAccessibilityTraitButton), nil); |
| 80 } | 80 } |
| 81 | 81 |
| 82 // Returns the GREYMatcher for the button which indicates that torch is on and | 82 // Returns the GREYMatcher for the button which indicates that torch is on and |
| 83 // which turns off the torch. | 83 // which turns off the torch. |
| 84 id<GREYMatcher> qrScannerTorchOnButton() { | 84 id<GREYMatcher> QrScannerTorchOnButton() { |
| 85 return grey_allOf(grey_accessibilityLabel(l10n_util::GetNSString( | 85 return grey_allOf(grey_accessibilityLabel(l10n_util::GetNSString( |
| 86 IDS_IOS_QR_SCANNER_TORCH_BUTTON_ACCESSIBILITY_LABEL)), | 86 IDS_IOS_QR_SCANNER_TORCH_BUTTON_ACCESSIBILITY_LABEL)), |
| 87 grey_accessibilityValue(l10n_util::GetNSString( | 87 grey_accessibilityValue(l10n_util::GetNSString( |
| 88 IDS_IOS_QR_SCANNER_TORCH_ON_ACCESSIBILITY_VALUE)), | 88 IDS_IOS_QR_SCANNER_TORCH_ON_ACCESSIBILITY_VALUE)), |
| 89 grey_accessibilityTrait(UIAccessibilityTraitButton), nil); | 89 grey_accessibilityTrait(UIAccessibilityTraitButton), nil); |
| 90 } | 90 } |
| 91 | 91 |
| 92 // Returns the GREYMatcher for the QR Scanner viewport caption. | 92 // Returns the GREYMatcher for the QR Scanner viewport caption. |
| 93 id<GREYMatcher> qrScannerViewportCaption() { | 93 id<GREYMatcher> QrScannerViewportCaption() { |
| 94 return staticTextWithAccessibilityLabelId( | 94 return StaticTextWithAccessibilityLabelId( |
| 95 IDS_IOS_QR_SCANNER_VIEWPORT_CAPTION); | 95 IDS_IOS_QR_SCANNER_VIEWPORT_CAPTION); |
| 96 } | 96 } |
| 97 | 97 |
| 98 // Returns the GREYMatcher for the back button in the web toolbar. | 98 // Returns the GREYMatcher for the back button in the web toolbar. |
| 99 id<GREYMatcher> webToolbarBackButton() { | 99 id<GREYMatcher> WebToolbarBackButton() { |
| 100 return buttonWithAccessibilityLabelId(IDS_ACCNAME_BACK); | 100 return ButtonWithAccessibilityLabelId(IDS_ACCNAME_BACK); |
| 101 } | 101 } |
| 102 | 102 |
| 103 // Returns the GREYMatcher for the Cancel button to dismiss a UIAlertController. | 103 // Returns the GREYMatcher for the Cancel button to dismiss a UIAlertController. |
| 104 id<GREYMatcher> dialogCancelButton() { | 104 id<GREYMatcher> DialogCancelButton() { |
| 105 return grey_allOf( | 105 return grey_allOf( |
| 106 grey_text(l10n_util::GetNSString(IDS_IOS_QR_SCANNER_ALERT_CANCEL)), | 106 grey_text(l10n_util::GetNSString(IDS_IOS_QR_SCANNER_ALERT_CANCEL)), |
| 107 grey_accessibilityTrait(UIAccessibilityTraitStaticText), nil); | 107 grey_accessibilityTrait(UIAccessibilityTraitStaticText), nil); |
| 108 } | 108 } |
| 109 | 109 |
| 110 // Opens the QR Scanner view using a command. | 110 // Opens the QR Scanner view using a command. |
| 111 // TODO(crbug.com/629776): Replace the command call with a UI action. | 111 // TODO(crbug.com/629776): Replace the command call with a UI action. |
| 112 void showQRScannerWithCommand() { | 112 void ShowQRScannerWithCommand() { |
| 113 base::scoped_nsobject<GenericChromeCommand> command( | 113 base::scoped_nsobject<GenericChromeCommand> command( |
| 114 [[GenericChromeCommand alloc] initWithTag:IDC_SHOW_QR_SCANNER]); | 114 [[GenericChromeCommand alloc] initWithTag:IDC_SHOW_QR_SCANNER]); |
| 115 chrome_test_util::RunCommandWithActiveViewController(command); | 115 chrome_test_util::RunCommandWithActiveViewController(command); |
| 116 } | 116 } |
| 117 | 117 |
| 118 // Taps the |button|. | 118 // Taps the |button|. |
| 119 void tapButton(id<GREYMatcher> button) { | 119 void TapButton(id<GREYMatcher> button) { |
| 120 [[EarlGrey selectElementWithMatcher:button] performAction:grey_tap()]; | 120 [[EarlGrey selectElementWithMatcher:button] performAction:grey_tap()]; |
| 121 } | 121 } |
| 122 | 122 |
| 123 // Appends the given |editText| to the |text| already in the omnibox and presses | 123 // Appends the given |editText| to the |text| already in the omnibox and presses |
| 124 // the keyboard return key. | 124 // the keyboard return key. |
| 125 void editOmniboxTextAndTapKeyboardReturn(std::string text, NSString* editText) { | 125 void EditOmniboxTextAndTapKeyboardReturn(std::string text, NSString* editText) { |
| 126 [[EarlGrey selectElementWithMatcher:omniboxText(text)] | 126 [[EarlGrey selectElementWithMatcher:OmniboxText(text)] |
| 127 performAction:grey_typeText([editText stringByAppendingString:@"\n"])]; | 127 performAction:grey_typeText([editText stringByAppendingString:@"\n"])]; |
| 128 } | 128 } |
| 129 | 129 |
| 130 // Presses the keyboard return key. | 130 // Presses the keyboard return key. |
| 131 void tapKeyboardReturnKeyInOmniboxWithText(std::string text) { | 131 void TapKeyboardReturnKeyInOmniboxWithText(std::string text) { |
| 132 [[EarlGrey selectElementWithMatcher:omniboxText(text)] | 132 [[EarlGrey selectElementWithMatcher:OmniboxText(text)] |
| 133 performAction:grey_typeText(@"\n")]; | 133 performAction:grey_typeText(@"\n")]; |
| 134 } | 134 } |
| 135 | 135 |
| 136 } // namespace | 136 } // namespace |
| 137 | 137 |
| 138 @interface QRScannerViewControllerTestCase : ChromeTestCase { | 138 @interface QRScannerViewControllerTestCase : ChromeTestCase { |
| 139 GURL _testURL; | 139 GURL _testURL; |
| 140 GURL _testURLEdited; | 140 GURL _testURLEdited; |
| 141 GURL _testQuery; | 141 GURL _testQuery; |
| 142 GURL _testQueryEdited; | 142 GURL _testQueryEdited; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 } | 180 } |
| 181 | 181 |
| 182 - (void)tearDown { | 182 - (void)tearDown { |
| 183 [super tearDown]; | 183 [super tearDown]; |
| 184 load_GURL_from_location_bar_swizzler_.reset(); | 184 load_GURL_from_location_bar_swizzler_.reset(); |
| 185 camera_controller_swizzler_.reset(); | 185 camera_controller_swizzler_.reset(); |
| 186 } | 186 } |
| 187 | 187 |
| 188 // Checks that the close button is visible, interactable, and enabled. | 188 // Checks that the close button is visible, interactable, and enabled. |
| 189 - (void)assertCloseButtonIsVisible { | 189 - (void)assertCloseButtonIsVisible { |
| 190 [[EarlGrey selectElementWithMatcher:qrScannerCloseButton()] | 190 [[EarlGrey selectElementWithMatcher:QrScannerCloseButton()] |
| 191 assertWithMatcher:visibleInteractableEnabled()]; | 191 assertWithMatcher:VisibleInteractableEnabled()]; |
| 192 } | 192 } |
| 193 | 193 |
| 194 // Checks that the close button is not visible. | 194 // Checks that the close button is not visible. |
| 195 - (void)assertCloseButtonIsNotVisible { | 195 - (void)assertCloseButtonIsNotVisible { |
| 196 [[EarlGrey selectElementWithMatcher:qrScannerCloseButton()] | 196 [[EarlGrey selectElementWithMatcher:QrScannerCloseButton()] |
| 197 assertWithMatcher:grey_notVisible()]; | 197 assertWithMatcher:grey_notVisible()]; |
| 198 } | 198 } |
| 199 | 199 |
| 200 // Checks that the torch off button is visible, interactable, and enabled, and | 200 // Checks that the torch off button is visible, interactable, and enabled, and |
| 201 // that the torch on button is not. | 201 // that the torch on button is not. |
| 202 - (void)assertTorchOffButtonIsVisible { | 202 - (void)assertTorchOffButtonIsVisible { |
| 203 [[EarlGrey selectElementWithMatcher:qrScannerTorchOffButton()] | 203 [[EarlGrey selectElementWithMatcher:QrScannerTorchOffButton()] |
| 204 assertWithMatcher:visibleInteractableEnabled()]; | 204 assertWithMatcher:VisibleInteractableEnabled()]; |
| 205 [[EarlGrey selectElementWithMatcher:qrScannerTorchOnButton()] | 205 [[EarlGrey selectElementWithMatcher:QrScannerTorchOnButton()] |
| 206 assertWithMatcher:grey_notVisible()]; | 206 assertWithMatcher:grey_notVisible()]; |
| 207 } | 207 } |
| 208 | 208 |
| 209 // Checks that the torch on button is visible, interactable, and enabled, and | 209 // Checks that the torch on button is visible, interactable, and enabled, and |
| 210 // that the torch off button is not. | 210 // that the torch off button is not. |
| 211 - (void)assertTorchOnButtonIsVisible { | 211 - (void)assertTorchOnButtonIsVisible { |
| 212 [[EarlGrey selectElementWithMatcher:qrScannerTorchOnButton()] | 212 [[EarlGrey selectElementWithMatcher:QrScannerTorchOnButton()] |
| 213 assertWithMatcher:visibleInteractableEnabled()]; | 213 assertWithMatcher:VisibleInteractableEnabled()]; |
| 214 [[EarlGrey selectElementWithMatcher:qrScannerTorchOffButton()] | 214 [[EarlGrey selectElementWithMatcher:QrScannerTorchOffButton()] |
| 215 assertWithMatcher:grey_notVisible()]; | 215 assertWithMatcher:grey_notVisible()]; |
| 216 } | 216 } |
| 217 | 217 |
| 218 // Checks that the torch off button is visible and disabled. | 218 // Checks that the torch off button is visible and disabled. |
| 219 - (void)assertTorchButtonIsDisabled { | 219 - (void)assertTorchButtonIsDisabled { |
| 220 [[EarlGrey selectElementWithMatcher:qrScannerTorchOffButton()] | 220 [[EarlGrey selectElementWithMatcher:QrScannerTorchOffButton()] |
| 221 assertWithMatcher:grey_allOf(grey_sufficientlyVisible(), | 221 assertWithMatcher:grey_allOf(grey_sufficientlyVisible(), |
| 222 grey_not(grey_enabled()), nil)]; | 222 grey_not(grey_enabled()), nil)]; |
| 223 } | 223 } |
| 224 | 224 |
| 225 // Checks that the camera viewport caption is visible. | 225 // Checks that the camera viewport caption is visible. |
| 226 - (void)assertCameraViewportCaptionIsVisible { | 226 - (void)assertCameraViewportCaptionIsVisible { |
| 227 [[EarlGrey selectElementWithMatcher:qrScannerViewportCaption()] | 227 [[EarlGrey selectElementWithMatcher:QrScannerViewportCaption()] |
| 228 assertWithMatcher:grey_sufficientlyVisible()]; | 228 assertWithMatcher:grey_sufficientlyVisible()]; |
| 229 } | 229 } |
| 230 | 230 |
| 231 // Checks that the close button, the camera preview, and the camera viewport | 231 // Checks that the close button, the camera preview, and the camera viewport |
| 232 // caption are visible. If |torch| is YES, checks that the torch off button is | 232 // caption are visible. If |torch| is YES, checks that the torch off button is |
| 233 // visible, otherwise checks that the torch button is disabled. If |preview| is | 233 // visible, otherwise checks that the torch button is disabled. If |preview| is |
| 234 // YES, checks that the preview is visible and of the same size as the QR | 234 // YES, checks that the preview is visible and of the same size as the QR |
| 235 // Scanner view, otherwise checks that the preview is in the view hierarchy but | 235 // Scanner view, otherwise checks that the preview is in the view hierarchy but |
| 236 // is hidden. | 236 // is hidden. |
| 237 - (void)assertQRScannerUIIsVisibleWithTorch:(BOOL)torch { | 237 - (void)assertQRScannerUIIsVisibleWithTorch:(BOOL)torch { |
| 238 [self assertCloseButtonIsVisible]; | 238 [self assertCloseButtonIsVisible]; |
| 239 [self assertCameraViewportCaptionIsVisible]; | 239 [self assertCameraViewportCaptionIsVisible]; |
| 240 if (torch) { | 240 if (torch) { |
| 241 [self assertTorchOffButtonIsVisible]; | 241 [self assertTorchOffButtonIsVisible]; |
| 242 } else { | 242 } else { |
| 243 [self assertTorchButtonIsDisabled]; | 243 [self assertTorchButtonIsDisabled]; |
| 244 } | 244 } |
| 245 } | 245 } |
| 246 | 246 |
| 247 // Presents the QR Scanner with a command, waits for it to be displayed, and | 247 // Presents the QR Scanner with a command, waits for it to be displayed, and |
| 248 // checks if all its views and buttons are visible. Checks that no alerts are | 248 // checks if all its views and buttons are visible. Checks that no alerts are |
| 249 // presented. | 249 // presented. |
| 250 - (void)showQRScannerAndCheckLayoutWithCameraMock:(id)mock { | 250 - (void)showQRScannerAndCheckLayoutWithCameraMock:(id)mock { |
| 251 UIViewController* bvc = [self currentBVC]; | 251 UIViewController* bvc = [self currentBVC]; |
| 252 [self assertModalOfClass:[QRScannerViewController class] | 252 [self assertModalOfClass:[QRScannerViewController class] |
| 253 isNotPresentedBy:bvc]; | 253 isNotPresentedBy:bvc]; |
| 254 [self assertModalOfClass:[UIAlertController class] isNotPresentedBy:bvc]; | 254 [self assertModalOfClass:[UIAlertController class] isNotPresentedBy:bvc]; |
| 255 | 255 |
| 256 [self addCameraControllerInitializationExpectations:mock]; | 256 [self addCameraControllerInitializationExpectations:mock]; |
| 257 showQRScannerWithCommand(); | 257 ShowQRScannerWithCommand(); |
| 258 [self waitForModalOfClass:[QRScannerViewController class] toAppearAbove:bvc]; | 258 [self waitForModalOfClass:[QRScannerViewController class] toAppearAbove:bvc]; |
| 259 [self assertQRScannerUIIsVisibleWithTorch:NO]; | 259 [self assertQRScannerUIIsVisibleWithTorch:NO]; |
| 260 [self assertModalOfClass:[UIAlertController class] | 260 [self assertModalOfClass:[UIAlertController class] |
| 261 isNotPresentedBy:[bvc presentedViewController]]; | 261 isNotPresentedBy:[bvc presentedViewController]]; |
| 262 [self assertModalOfClass:[UIAlertController class] isNotPresentedBy:bvc]; | 262 [self assertModalOfClass:[UIAlertController class] isNotPresentedBy:bvc]; |
| 263 } | 263 } |
| 264 | 264 |
| 265 // Closes the QR scanner by tapping the close button and waits for it to | 265 // Closes the QR scanner by tapping the close button and waits for it to |
| 266 // disappear. | 266 // disappear. |
| 267 - (void)closeQRScannerWithCameraMock:(id)mock { | 267 - (void)closeQRScannerWithCameraMock:(id)mock { |
| 268 [self addCameraControllerDismissalExpectations:mock]; | 268 [self addCameraControllerDismissalExpectations:mock]; |
| 269 tapButton(qrScannerCloseButton()); | 269 TapButton(QrScannerCloseButton()); |
| 270 [self waitForModalOfClass:[QRScannerViewController class] | 270 [self waitForModalOfClass:[QRScannerViewController class] |
| 271 toDisappearFromAbove:[self currentBVC]]; | 271 toDisappearFromAbove:[self currentBVC]]; |
| 272 } | 272 } |
| 273 | 273 |
| 274 // Returns the current BrowserViewController. | 274 // Returns the current BrowserViewController. |
| 275 - (UIViewController*)currentBVC { | 275 - (UIViewController*)currentBVC { |
| 276 // TODO(crbug.com/629516): Evaluate moving this into a common utility. | 276 // TODO(crbug.com/629516): Evaluate moving this into a common utility. |
| 277 MainController* mainController = chrome_test_util::GetMainController(); | 277 MainController* mainController = chrome_test_util::GetMainController(); |
| 278 return [[mainController browserViewInformation] currentBVC]; | 278 return [[mainController browserViewInformation] currentBVC]; |
| 279 } | 279 } |
| 280 | 280 |
| 281 // Checks that the omnibox is visible and contains |text|. | 281 // Checks that the omnibox is visible and contains |text|. |
| 282 - (void)assertOmniboxIsVisibleWithText:(std::string)text { | 282 - (void)assertOmniboxIsVisibleWithText:(std::string)text { |
| 283 [[EarlGrey selectElementWithMatcher:omniboxText(text)] | 283 [[EarlGrey selectElementWithMatcher:OmniboxText(text)] |
| 284 assertWithMatcher:grey_notNil()]; | 284 assertWithMatcher:grey_notNil()]; |
| 285 } | 285 } |
| 286 | 286 |
| 287 // Checks that the page that is currently loaded contains the |response|. | 287 // Checks that the page that is currently loaded contains the |response|. |
| 288 - (void)assertTestURLIsLoaded:(std::string)response { | 288 - (void)assertTestURLIsLoaded:(std::string)response { |
| 289 id<GREYMatcher> testURLResponseMatcher = | 289 id<GREYMatcher> testURLResponseMatcher = |
| 290 chrome_test_util::webViewContainingText(response); | 290 chrome_test_util::WebViewContainingText(response); |
| 291 [[EarlGrey selectElementWithMatcher:testURLResponseMatcher] | 291 [[EarlGrey selectElementWithMatcher:testURLResponseMatcher] |
| 292 assertWithMatcher:grey_notNil()]; | 292 assertWithMatcher:grey_notNil()]; |
| 293 } | 293 } |
| 294 | 294 |
| 295 #pragma mark helpers for dialogs | 295 #pragma mark helpers for dialogs |
| 296 | 296 |
| 297 // Checks that the modal presented by |viewController| is of class |klass|. | 297 // Checks that the modal presented by |viewController| is of class |klass|. |
| 298 - (void)assertModalOfClass:(Class)klass | 298 - (void)assertModalOfClass:(Class)klass |
| 299 isPresentedBy:(UIViewController*)viewController { | 299 isPresentedBy:(UIViewController*)viewController { |
| 300 UIViewController* modal = [viewController presentedViewController]; | 300 UIViewController* modal = [viewController presentedViewController]; |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 538 // Open the QR scanner. | 538 // Open the QR scanner. |
| 539 [self showQRScannerAndCheckLayoutWithCameraMock:cameraControllerMock]; | 539 [self showQRScannerAndCheckLayoutWithCameraMock:cameraControllerMock]; |
| 540 | 540 |
| 541 // Torch becomes available. | 541 // Torch becomes available. |
| 542 [self callTorchAvailabilityChanged:YES]; | 542 [self callTorchAvailabilityChanged:YES]; |
| 543 [self assertQRScannerUIIsVisibleWithTorch:YES]; | 543 [self assertQRScannerUIIsVisibleWithTorch:YES]; |
| 544 | 544 |
| 545 // Turn torch on. | 545 // Turn torch on. |
| 546 [self addCameraControllerTorchOnExpectations:cameraControllerMock]; | 546 [self addCameraControllerTorchOnExpectations:cameraControllerMock]; |
| 547 [self assertTorchOffButtonIsVisible]; | 547 [self assertTorchOffButtonIsVisible]; |
| 548 tapButton(qrScannerTorchOffButton()); | 548 TapButton(QrScannerTorchOffButton()); |
| 549 [self assertTorchOffButtonIsVisible]; | 549 [self assertTorchOffButtonIsVisible]; |
| 550 | 550 |
| 551 // Torch becomes active. | 551 // Torch becomes active. |
| 552 [self callTorchStateChanged:YES]; | 552 [self callTorchStateChanged:YES]; |
| 553 [self assertTorchOnButtonIsVisible]; | 553 [self assertTorchOnButtonIsVisible]; |
| 554 | 554 |
| 555 // Turn torch off. | 555 // Turn torch off. |
| 556 [self addCameraControllerTorchOffExpectations:cameraControllerMock]; | 556 [self addCameraControllerTorchOffExpectations:cameraControllerMock]; |
| 557 tapButton(qrScannerTorchOnButton()); | 557 TapButton(QrScannerTorchOnButton()); |
| 558 [self assertTorchOnButtonIsVisible]; | 558 [self assertTorchOnButtonIsVisible]; |
| 559 | 559 |
| 560 // Torch becomes inactive. | 560 // Torch becomes inactive. |
| 561 [self callTorchStateChanged:NO]; | 561 [self callTorchStateChanged:NO]; |
| 562 [self assertTorchOffButtonIsVisible]; | 562 [self assertTorchOffButtonIsVisible]; |
| 563 | 563 |
| 564 // Close the QR scanner. | 564 // Close the QR scanner. |
| 565 [self closeQRScannerWithCameraMock:cameraControllerMock]; | 565 [self closeQRScannerWithCameraMock:cameraControllerMock]; |
| 566 [cameraControllerMock verify]; | 566 [cameraControllerMock verify]; |
| 567 } | 567 } |
| 568 | 568 |
| 569 // Tests that if the QR scanner is closed while the torch is on, the torch is | 569 // Tests that if the QR scanner is closed while the torch is on, the torch is |
| 570 // switched off and the correct button indicating that the torch is off is shown | 570 // switched off and the correct button indicating that the torch is off is shown |
| 571 // when the scanner is opened again. | 571 // when the scanner is opened again. |
| 572 - (void)testTorchButtonIsResetWhenQRScannerIsReopened { | 572 - (void)testTorchButtonIsResetWhenQRScannerIsReopened { |
| 573 id cameraControllerMock = | 573 id cameraControllerMock = |
| 574 [self getCameraControllerMockWithAuthorizationStatus: | 574 [self getCameraControllerMockWithAuthorizationStatus: |
| 575 AVAuthorizationStatusAuthorized]; | 575 AVAuthorizationStatusAuthorized]; |
| 576 [self swizzleCameraController:cameraControllerMock]; | 576 [self swizzleCameraController:cameraControllerMock]; |
| 577 | 577 |
| 578 // Open the QR scanner. | 578 // Open the QR scanner. |
| 579 [self showQRScannerAndCheckLayoutWithCameraMock:cameraControllerMock]; | 579 [self showQRScannerAndCheckLayoutWithCameraMock:cameraControllerMock]; |
| 580 [self assertQRScannerUIIsVisibleWithTorch:NO]; | 580 [self assertQRScannerUIIsVisibleWithTorch:NO]; |
| 581 [self callTorchAvailabilityChanged:YES]; | 581 [self callTorchAvailabilityChanged:YES]; |
| 582 [self assertQRScannerUIIsVisibleWithTorch:YES]; | 582 [self assertQRScannerUIIsVisibleWithTorch:YES]; |
| 583 | 583 |
| 584 // Turn torch on. | 584 // Turn torch on. |
| 585 [self addCameraControllerTorchOnExpectations:cameraControllerMock]; | 585 [self addCameraControllerTorchOnExpectations:cameraControllerMock]; |
| 586 tapButton(qrScannerTorchOffButton()); | 586 TapButton(QrScannerTorchOffButton()); |
| 587 [self callTorchStateChanged:YES]; | 587 [self callTorchStateChanged:YES]; |
| 588 [self assertTorchOnButtonIsVisible]; | 588 [self assertTorchOnButtonIsVisible]; |
| 589 | 589 |
| 590 // Close the QR scanner. | 590 // Close the QR scanner. |
| 591 [self closeQRScannerWithCameraMock:cameraControllerMock]; | 591 [self closeQRScannerWithCameraMock:cameraControllerMock]; |
| 592 | 592 |
| 593 // Reopen the QR scanner. | 593 // Reopen the QR scanner. |
| 594 [self showQRScannerAndCheckLayoutWithCameraMock:cameraControllerMock]; | 594 [self showQRScannerAndCheckLayoutWithCameraMock:cameraControllerMock]; |
| 595 [self callTorchAvailabilityChanged:YES]; | 595 [self callTorchAvailabilityChanged:YES]; |
| 596 [self assertTorchOffButtonIsVisible]; | 596 [self assertTorchOffButtonIsVisible]; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 | 638 |
| 639 UIViewController* bvc = [self currentBVC]; | 639 UIViewController* bvc = [self currentBVC]; |
| 640 [self assertModalOfClass:[QRScannerViewController class] | 640 [self assertModalOfClass:[QRScannerViewController class] |
| 641 isNotPresentedBy:bvc]; | 641 isNotPresentedBy:bvc]; |
| 642 [self assertModalOfClass:[UIAlertController class] isNotPresentedBy:bvc]; | 642 [self assertModalOfClass:[UIAlertController class] isNotPresentedBy:bvc]; |
| 643 id cameraControllerMock = | 643 id cameraControllerMock = |
| 644 [self getCameraControllerMockWithAuthorizationStatus: | 644 [self getCameraControllerMockWithAuthorizationStatus: |
| 645 AVAuthorizationStatusDenied]; | 645 AVAuthorizationStatusDenied]; |
| 646 [self swizzleCameraController:cameraControllerMock]; | 646 [self swizzleCameraController:cameraControllerMock]; |
| 647 | 647 |
| 648 showQRScannerWithCommand(); | 648 ShowQRScannerWithCommand(); |
| 649 [self assertModalOfClass:[QRScannerViewController class] | 649 [self assertModalOfClass:[QRScannerViewController class] |
| 650 isNotPresentedBy:bvc]; | 650 isNotPresentedBy:bvc]; |
| 651 [self waitForModalOfClass:[UIAlertController class] toAppearAbove:bvc]; | 651 [self waitForModalOfClass:[UIAlertController class] toAppearAbove:bvc]; |
| 652 | 652 |
| 653 tapButton(dialogCancelButton()); | 653 TapButton(DialogCancelButton()); |
| 654 [self waitForModalOfClass:[UIAlertController class] toDisappearFromAbove:bvc]; | 654 [self waitForModalOfClass:[UIAlertController class] toDisappearFromAbove:bvc]; |
| 655 } | 655 } |
| 656 | 656 |
| 657 // Tests that a UIAlertController is presented by the QRScannerViewController if | 657 // Tests that a UIAlertController is presented by the QRScannerViewController if |
| 658 // the camera state changes after the QRScannerViewController is presented. | 658 // the camera state changes after the QRScannerViewController is presented. |
| 659 - (void)testDialogIsDisplayedIfCameraStateChanges { | 659 - (void)testDialogIsDisplayedIfCameraStateChanges { |
| 660 // TODO(crbug.com/663026): Reenable the test for devices. | 660 // TODO(crbug.com/663026): Reenable the test for devices. |
| 661 #if !TARGET_IPHONE_SIMULATOR | 661 #if !TARGET_IPHONE_SIMULATOR |
| 662 EARL_GREY_TEST_DISABLED(@"Disabled for devices because existing system " | 662 EARL_GREY_TEST_DISABLED(@"Disabled for devices because existing system " |
| 663 @"alerts would prevent app alerts to present " | 663 @"alerts would prevent app alerts to present " |
| 664 @"correctly."); | 664 @"correctly."); |
| 665 #endif | 665 #endif |
| 666 | 666 |
| 667 id cameraControllerMock = | 667 id cameraControllerMock = |
| 668 [self getCameraControllerMockWithAuthorizationStatus: | 668 [self getCameraControllerMockWithAuthorizationStatus: |
| 669 AVAuthorizationStatusAuthorized]; | 669 AVAuthorizationStatusAuthorized]; |
| 670 [self swizzleCameraController:cameraControllerMock]; | 670 [self swizzleCameraController:cameraControllerMock]; |
| 671 | 671 |
| 672 std::vector<CameraState> tests{MULTIPLE_FOREGROUND_APPS, CAMERA_UNAVAILABLE, | 672 std::vector<CameraState> tests{MULTIPLE_FOREGROUND_APPS, CAMERA_UNAVAILABLE, |
| 673 CAMERA_PERMISSION_DENIED, | 673 CAMERA_PERMISSION_DENIED, |
| 674 CAMERA_IN_USE_BY_ANOTHER_APPLICATION}; | 674 CAMERA_IN_USE_BY_ANOTHER_APPLICATION}; |
| 675 | 675 |
| 676 for (const CameraState& state : tests) { | 676 for (const CameraState& state : tests) { |
| 677 [self showQRScannerAndCheckLayoutWithCameraMock:cameraControllerMock]; | 677 [self showQRScannerAndCheckLayoutWithCameraMock:cameraControllerMock]; |
| 678 [self callCameraStateChanged:state]; | 678 [self callCameraStateChanged:state]; |
| 679 [self assertQRScannerIsPresentingADialogForState:state]; | 679 [self assertQRScannerIsPresentingADialogForState:state]; |
| 680 | 680 |
| 681 // Close the dialog. | 681 // Close the dialog. |
| 682 [self addCameraControllerDismissalExpectations:cameraControllerMock]; | 682 [self addCameraControllerDismissalExpectations:cameraControllerMock]; |
| 683 tapButton(dialogCancelButton()); | 683 TapButton(DialogCancelButton()); |
| 684 UIViewController* bvc = [self currentBVC]; | 684 UIViewController* bvc = [self currentBVC]; |
| 685 [self waitForModalOfClass:[QRScannerViewController class] | 685 [self waitForModalOfClass:[QRScannerViewController class] |
| 686 toDisappearFromAbove:bvc]; | 686 toDisappearFromAbove:bvc]; |
| 687 [self assertModalOfClass:[UIAlertController class] isNotPresentedBy:bvc]; | 687 [self assertModalOfClass:[UIAlertController class] isNotPresentedBy:bvc]; |
| 688 } | 688 } |
| 689 | 689 |
| 690 [cameraControllerMock verify]; | 690 [cameraControllerMock verify]; |
| 691 } | 691 } |
| 692 | 692 |
| 693 // Tests that a new dialog replaces an old dialog if the camera state changes. | 693 // Tests that a new dialog replaces an old dialog if the camera state changes. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 716 | 716 |
| 717 for (const CameraState& state : tests) { | 717 for (const CameraState& state : tests) { |
| 718 [self callCameraStateChanged:state]; | 718 [self callCameraStateChanged:state]; |
| 719 [self assertQRScannerIsPresentingADialogForState:state]; | 719 [self assertQRScannerIsPresentingADialogForState:state]; |
| 720 [self assertQRScannerIsNotPresentingADialogForState:currentState]; | 720 [self assertQRScannerIsNotPresentingADialogForState:currentState]; |
| 721 currentState = state; | 721 currentState = state; |
| 722 } | 722 } |
| 723 | 723 |
| 724 // Cancel the dialog. | 724 // Cancel the dialog. |
| 725 [self addCameraControllerDismissalExpectations:cameraControllerMock]; | 725 [self addCameraControllerDismissalExpectations:cameraControllerMock]; |
| 726 tapButton(dialogCancelButton()); | 726 TapButton(DialogCancelButton()); |
| 727 [self waitForModalOfClass:[QRScannerViewController class] | 727 [self waitForModalOfClass:[QRScannerViewController class] |
| 728 toDisappearFromAbove:[self currentBVC]]; | 728 toDisappearFromAbove:[self currentBVC]]; |
| 729 [self assertModalOfClass:[UIAlertController class] | 729 [self assertModalOfClass:[UIAlertController class] |
| 730 isNotPresentedBy:[self currentBVC]]; | 730 isNotPresentedBy:[self currentBVC]]; |
| 731 | 731 |
| 732 [cameraControllerMock verify]; | 732 [cameraControllerMock verify]; |
| 733 } | 733 } |
| 734 | 734 |
| 735 // Tests that an error dialog is dismissed if the camera becomes available. | 735 // Tests that an error dialog is dismissed if the camera becomes available. |
| 736 - (void)testDialogDismissedIfCameraBecomesAvailable { | 736 - (void)testDialogDismissedIfCameraBecomesAvailable { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 782 [self addCameraControllerDismissalExpectations:cameraControllerMock]; | 782 [self addCameraControllerDismissalExpectations:cameraControllerMock]; |
| 783 [self callReceiveQRScannerResult:base::SysUTF8ToNSString(result)]; | 783 [self callReceiveQRScannerResult:base::SysUTF8ToNSString(result)]; |
| 784 | 784 |
| 785 [self waitForModalOfClass:[QRScannerViewController class] | 785 [self waitForModalOfClass:[QRScannerViewController class] |
| 786 toDisappearFromAbove:[self currentBVC]]; | 786 toDisappearFromAbove:[self currentBVC]]; |
| 787 [cameraControllerMock verify]; | 787 [cameraControllerMock verify]; |
| 788 | 788 |
| 789 // Optionally edit the text in the omnibox before pressing return. | 789 // Optionally edit the text in the omnibox before pressing return. |
| 790 [self assertOmniboxIsVisibleWithText:result]; | 790 [self assertOmniboxIsVisibleWithText:result]; |
| 791 if (editString != nil) { | 791 if (editString != nil) { |
| 792 editOmniboxTextAndTapKeyboardReturn(result, editString); | 792 EditOmniboxTextAndTapKeyboardReturn(result, editString); |
| 793 } else { | 793 } else { |
| 794 tapKeyboardReturnKeyInOmniboxWithText(result); | 794 TapKeyboardReturnKeyInOmniboxWithText(result); |
| 795 } | 795 } |
| 796 [self assertTestURLIsLoaded:response]; | 796 [self assertTestURLIsLoaded:response]; |
| 797 | 797 |
| 798 // Press the back button to get back to the NTP. | 798 // Press the back button to get back to the NTP. |
| 799 tapButton(webToolbarBackButton()); | 799 TapButton(WebToolbarBackButton()); |
| 800 [self assertModalOfClass:[QRScannerViewController class] | 800 [self assertModalOfClass:[QRScannerViewController class] |
| 801 isNotPresentedBy:[self currentBVC]]; | 801 isNotPresentedBy:[self currentBVC]]; |
| 802 } | 802 } |
| 803 | 803 |
| 804 // Test that the correct page is loaded if the scanner result is a URL. | 804 // Test that the correct page is loaded if the scanner result is a URL. |
| 805 - (void)testReceivingQRScannerURLResult { | 805 - (void)testReceivingQRScannerURLResult { |
| 806 [self doTestReceivingResult:_testURL.GetContent() | 806 [self doTestReceivingResult:_testURL.GetContent() |
| 807 response:kTestURLResponse | 807 response:kTestURLResponse |
| 808 edit:nil]; | 808 edit:nil]; |
| 809 } | 809 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 825 // Test that the correct page is loaded if the scanner result is a search query | 825 // Test that the correct page is loaded if the scanner result is a search query |
| 826 // which is then manually edited. | 826 // which is then manually edited. |
| 827 - (void)testReceivingQRScannerSearchQueryResultAndEditingTheQuery { | 827 - (void)testReceivingQRScannerSearchQueryResultAndEditingTheQuery { |
| 828 [self swizzleWebToolbarControllerLoadGURLFromLocationBar:_testQueryEdited]; | 828 [self swizzleWebToolbarControllerLoadGURLFromLocationBar:_testQueryEdited]; |
| 829 [self doTestReceivingResult:kTestQuery | 829 [self doTestReceivingResult:kTestQuery |
| 830 response:kTestQueryEditedResponse | 830 response:kTestQueryEditedResponse |
| 831 edit:@"\bedited"]; | 831 edit:@"\bedited"]; |
| 832 } | 832 } |
| 833 | 833 |
| 834 @end | 834 @end |
| OLD | NEW |