• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2024 The Chromium Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5from __future__ import annotations
6
7import datetime as dt
8from typing import TYPE_CHECKING, Iterable
9
10from crossbench.benchmarks.loading.page.base import Page, get_action_runner
11from crossbench.benchmarks.loading.playback_controller import \
12    PlaybackController
13from crossbench.benchmarks.loading.tab_controller import TabController
14
15if TYPE_CHECKING:
16  from crossbench.action_runner.base import ActionRunner
17  from crossbench.runner.run import Run
18  from crossbench.types import JsonDict
19
20
21class CombinedPage(Page):
22
23  def __init__(self,
24               pages: Iterable[Page],
25               name: str = "combined",
26               playback: PlaybackController = PlaybackController.default(),
27               tabs: TabController = TabController.default(),
28               about_blank_duration: dt.timedelta = dt.timedelta()):
29    self._pages = tuple(pages)
30    assert self._pages, "No sub-pages provided for CombinedPage"
31    assert len(self._pages) >= 1, "Combined Page needs at least one page"
32    self._tabs = tabs
33
34    duration = dt.timedelta()
35    for page in self._pages:
36      page.set_parent(self)
37      duration += page.duration
38    super().__init__(name, duration, playback, tabs, about_blank_duration)
39    self.url = None
40
41  @property
42  def tabs(self) -> TabController:
43    return self._tabs
44
45  @property
46  def pages(self) -> Iterable[Page]:
47    return self._pages
48
49  @property
50  def first_url(self) -> str:
51    return self._pages[0].first_url
52
53  def details_json(self) -> JsonDict:
54    result = super().details_json()
55    result["pages"] = list(page.details_json() for page in self._pages)
56    return result
57
58  def run(self, run: Run) -> None:
59    action_runner = get_action_runner(run)
60    multiple_tabs = self.tabs.multiple_tabs
61    for _ in self._playback:
62      action_runner.run_combined_page(run, self, multiple_tabs)
63
64  def run_with(self, run: Run, action_runner: ActionRunner,
65               multiple_tabs: bool) -> None:
66    action_runner.run_combined_page(run, self, multiple_tabs)
67
68  def __str__(self) -> str:
69    combined_name = ",".join(page.name for page in self._pages)
70    return f"CombinedPage({combined_name})"
71