chromium/tools/perf/page_sets/companion/basic_companion_story.py

# 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 json
import subprocess
from page_sets.desktop_ui.multitab_story import MultiTabStory
from page_sets.desktop_ui.ui_devtools_utils import ClickOn, InputText, \
    PressKey, SHIFT_DOWN
from page_sets.companion.browser_element_identifiers import \
    kToolbarSidePanelButtonElementId, kSidePanelComboboxElementId
from page_sets.companion.histograms import _CQ, _PROMO_EVENT, _SEARCH_BOX, \
    _STARTUP, _ZERO_STATE
from page_sets.login_helpers import google_login
from page_sets.data.companion_test_sites import SITES

SCREENSHOT_PATH = "/tmp/"

_GOOGLE_URL = "https://www.google.com/"
_TEST_SEARCH_URL = "https://www.google.com/search?q=test"
_TEST_PAGE_URL = "https://www.westelm.com"
_BLANK_URL = "about:blank"
_COMPANION_URL = "https://lens.google.com/companion?pli=1"


class CompanionStory(MultiTabStory):
  """Base class for companion stories"""
  URL_LIST = [_TEST_SEARCH_URL]
  URL = URL_LIST[0]
  WAIT_FOR_NETWORK_QUIESCENCE = True

  def RunPageInteractions(self, action_runner):
    action_runner.tab.Navigate(_BLANK_URL)
    action_runner.Wait(1)
    assert action_runner.tab.url == _BLANK_URL
    self.InteractWithPage(action_runner)

  def ToggleSidePanel(self, action_runner):
    ClickOn(self._devtools, element_id=kToolbarSidePanelButtonElementId)
    action_runner.Wait(3)

  def OpenCompanion(self, action_runner):
    self.ToggleSidePanel(action_runner)
    combobox_node_id = self._devtools.QueryNodes("id:%s" %
                                                 kSidePanelComboboxElementId)[0]
    PressKey(self._devtools, combobox_node_id, " ")
    action_runner.Wait(1)
    window_node_id = self._devtools.QueryNodes("<Window>")[0]
    PressKey(self._devtools, window_node_id, "ArrowUp")
    PressKey(self._devtools, window_node_id, "Return")

  def LogIn(self, action_runner):
    google_login.NewLoginGoogleAccount(action_runner, "intelligence")

  def SanityHistogramCheck(self, action_runner):
    action_runner.tab.Navigate(_GOOGLE_URL)
    action_runner.Wait(1)
    assert action_runner.tab.url == _GOOGLE_URL, "%s" % action_runner.tab.url
    histogram = self.FetchHistogram(action_runner, _STARTUP)
    assert histogram["count"] == 1

  def ConductHistogramCheck(self,
                            action_runner,
                            histogram_name,
                            expected_empty=False,
                            expected_count=None):
    histogram = self.FetchHistogram(action_runner, histogram_name)
    if expected_empty:
      assert not histogram, "expected non-existent %s histogram, got %s" % \
          (histogram_name, histogram)
    else:
      assert histogram, "%s histogram is non-existent" % histogram_name

    if expected_count:
      assert histogram['count'] == expected_count, \
          "Expected %s, got %s for histogram %s" % (expected_count,
                                                     histogram['count'],
                                                     histogram_name)

  def FetchHistogram(self, action_runner, name):
    js = "statsCollectionController.getBrowserHistogram('%s');" % name
    return json.loads(action_runner.EvaluateJavaScript(js))

  def InteractWithPage(self, action_runner):
    pass


class CompanionStoryBasicOpen(CompanionStory):
  NAME = 'companion:basic_open_logged_in'

  def InteractWithPage(self, action_runner):
    self.SanityHistogramCheck(action_runner)
    self.LogIn(action_runner)
    action_runner.Wait(1)
    action_runner.tab.Navigate(_TEST_PAGE_URL)
    action_runner.Wait(3)

    # Open companion and ensure features loaded.
    self.OpenCompanion(action_runner)
    action_runner.Wait(10)
    self.ConductHistogramCheck(action_runner, _ZERO_STATE)
    self.ConductHistogramCheck(action_runner, _CQ)


class CompanionStoryBasicOpenLoggedOut(CompanionStory):
  NAME = 'companion:basic_open_logged_out'

  def InteractWithPage(self, action_runner):
    self.SanityHistogramCheck(action_runner)
    action_runner.tab.Navigate(_TEST_PAGE_URL)
    action_runner.Wait(3)

    # Open companion and ensure features loaded.
    self.OpenCompanion(action_runner)
    action_runner.Wait(10)
    self.ConductHistogramCheck(action_runner, _ZERO_STATE)
    self.ConductHistogramCheck(action_runner, _PROMO_EVENT)
    self.ConductHistogramCheck(action_runner, _CQ, expected_empty=True)


class CompanionStorySRP(CompanionStory):
  NAME = 'companion:srp'

  def ConductSideSearch(self, action_runner):
    action_runner.Wait(2)
    node_id = self._devtools.QueryNodes('<Window>')[0]
    action_runner.Wait(2)
    PressKey(self._devtools, node_id, 'Tab', SHIFT_DOWN)
    PressKey(self._devtools, node_id, 'Tab', SHIFT_DOWN)
    PressKey(self._devtools, node_id, 'Tab', SHIFT_DOWN)
    InputText(self._devtools, node_id, 'test input')
    action_runner.Wait(1)
    PressKey(self._devtools, node_id, 'Tab', SHIFT_DOWN)
    PressKey(self._devtools, node_id, ' ')
    PressKey(self._devtools, node_id, ' ')
    action_runner.PressKey(' ')
    action_runner.PressKey(' ')

  def InteractWithPage(self, action_runner):
    self.SanityHistogramCheck(action_runner)
    self.LogIn(action_runner)
    action_runner.Wait(1)
    action_runner.tab.Navigate(_TEST_PAGE_URL)
    action_runner.Wait(3)

    # Open companion and ensure features loaded.
    self.OpenCompanion(action_runner)
    action_runner.Wait(10)
    self.ConductHistogramCheck(action_runner, _ZERO_STATE)
    self.ConductHistogramCheck(action_runner, _PROMO_EVENT)
    self.ConductHistogramCheck(action_runner, _CQ)

    # Conduct Side Search
    self.ConductHistogramCheck(action_runner, _SEARCH_BOX, expected_empty=True)
    self.ConductSideSearch(action_runner)
    self.ConductHistogramCheck(action_runner, _SEARCH_BOX)


class CompanionStoryScreenshot(CompanionStory):
  NAME = 'companion:screenshot'

  def InteractWithPage(self, action_runner):
    self.SanityHistogramCheck(action_runner)
    self.LogIn(action_runner)
    action_runner.Wait(5)
    self.OpenCompanion(action_runner)

    for count, site in enumerate(SITES):
      action_runner.tab.Navigate(site)
      action_runner.Wait(15)
      subprocess.call(["scrot", SCREENSHOT_PATH + str(count) + ".png"])