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