chromium/ios/chrome/browser/ui/tab_switcher/test/tabs_egtest_util.mm

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import "ios/chrome/browser/ui/tab_switcher/test/tabs_egtest_util.h"

#import "base/ios/block_types.h"
#import "base/test/ios/wait_util.h"
#import "base/time/time.h"
#import "ios/chrome/browser/ui/popup_menu/popup_menu_constants.h"
#import "ios/chrome/browser/ui/tab_switcher/test/query_title_server_util.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/testing/earl_grey/earl_grey_test.h"
#import "net/test/embedded_test_server/embedded_test_server.h"

namespace {

NSString* const kRegularTabTitlePrefix = @"RegularTab";
NSString* const kPinnedTabTitlePrefix = @"PinnedTab";

constexpr base::TimeDelta kSnackbarAppearanceTimeout = base::Seconds(5);
constexpr base::TimeDelta kSnackbarDisappearanceTimeout = base::Seconds(11);

}  // namespace

// Creates a regular tab with `title` using `test_server`.
void CreateRegularTab(net::test_server::EmbeddedTestServer* test_server,
                      NSString* title) {
  [ChromeEarlGreyUI openNewTab];
  [ChromeEarlGrey loadURL:GetQueryTitleURL(test_server, title)];
}

// Create `tabs_count` of regular tabs.
void CreateRegularTabs(int tabs_count,
                       net::test_server::EmbeddedTestServer* test_server) {
  for (int index = 0; index < tabs_count; ++index) {
    NSString* title =
        [kRegularTabTitlePrefix stringByAppendingFormat:@"%d", index];

    CreateRegularTab(test_server, title);
  }
}

// Create `tabs_count` of pinned tabs.
void CreatePinnedTabs(int tabs_count,
                      net::test_server::EmbeddedTestServer* test_server) {
  for (int index = 0; index < tabs_count; ++index) {
    NSString* title =
        [kPinnedTabTitlePrefix stringByAppendingFormat:@"%d", index];

    CreateRegularTab(test_server, title);
    [ChromeEarlGrey pinCurrentTab];
  }
}

id<GREYMatcher> TabGridCell() {
  return grey_allOf(grey_kindOfClassName(@"GridCell"),
                    grey_sufficientlyVisible(), nil);
}

id<GREYMatcher> TabWithTitle(NSString* title) {
  return grey_allOf(TabGridCell(), grey_accessibilityLabel(title),
                    grey_sufficientlyVisible(), nil);
}

id<GREYMatcher> TabWithTitleAndIndex(NSString* title, unsigned int index) {
  return grey_allOf(TabWithTitle(title),
                    chrome_test_util::TabGridCellAtIndex(index), nil);
}

void WaitForSnackbarTriggeredByTappingItem(NSString* snackbarLabel,
                                           id<GREYMatcher> matcher) {
  [[EarlGrey selectElementWithMatcher:matcher] performAction:grey_tap()];

  // Wait for the snackbar to appear.
  id<GREYMatcher> snackbar_matcher =
      grey_accessibilityID(@"MDCSnackbarMessageTitleAutomationIdentifier");
  ConditionBlock wait_for_appearance = ^{
    NSError* error = nil;
    [[EarlGrey selectElementWithMatcher:snackbar_matcher]
        assertWithMatcher:grey_notNil()
                    error:&error];
    return error == nil;
  };
  if (!wait_for_appearance()) {
    GREYAssert(base::test::ios::WaitUntilConditionOrTimeout(
                   kSnackbarAppearanceTimeout, wait_for_appearance),
               @"Snackbar did not appear.");
  }

  // Tap the snackbar to make it disappear. (It used to be that snackbars all
  // disappeared after a delay, but not anymore: snackbars with an action now
  // stay on-screen until interacted with).
  [[EarlGrey selectElementWithMatcher:snackbar_matcher]
      performAction:grey_tap()];

  // Wait for the snackbar to disappear.
  ConditionBlock wait_for_disappearance = ^{
    NSError* error = nil;
    [[EarlGrey selectElementWithMatcher:snackbar_matcher]
        assertWithMatcher:grey_nil()
                    error:&error];
    return error == nil;
  };
  GREYAssert(base::test::ios::WaitUntilConditionOrTimeout(
                 kSnackbarDisappearanceTimeout, wait_for_disappearance),
             @"Snackbar did not disappear.");
}