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 abc 8import dataclasses 9from typing import Any, Dict, Iterator 10 11from crossbench.config import ConfigObject 12from crossbench.parse import NumberParser 13 14 15class TabController(ConfigObject): 16 multiple_tabs: bool 17 is_forever: bool 18 19 @classmethod 20 def parse_dict(cls, config: Dict[str, Any]) -> TabController: 21 raise NotImplementedError("Cannot create tab controller from dict") 22 23 @classmethod 24 def parse_str(cls, value: str) -> TabController: 25 if not value or value == "single": 26 return cls.single() 27 if value in ("inf", "infinity"): 28 return cls.forever() 29 loops = NumberParser.positive_int(value, "Repeat-count") 30 return cls.repeat(loops) 31 32 @classmethod 33 def default(cls) -> TabController: 34 return cls.single() 35 36 @classmethod 37 def single(cls) -> TabController: 38 return SingleTabController() 39 40 @classmethod 41 def multiple(cls) -> TabController: 42 return RepeatTabController(1) 43 44 @classmethod 45 def repeat(cls, count: int) -> RepeatTabController: 46 return RepeatTabController(count) 47 48 @classmethod 49 def forever(cls) -> TabController: 50 return ForeverTabController() 51 52 @abc.abstractmethod 53 def __iter__(self) -> Iterator[None]: 54 pass 55 56 57@dataclasses.dataclass(frozen=True) 58class SingleTabController(TabController): 59 """ 60 Open given urls in one tab sequentially. 61 """ 62 multiple_tabs: bool = False 63 is_forever: bool = False 64 65 def __iter__(self) -> Iterator[None]: 66 yield None 67 68 69@dataclasses.dataclass(frozen=True) 70class ForeverTabController(TabController): 71 """ 72 Open given urls in separate tabs and repeat infinitely until 73 one of the tabs gets discarded. 74 75 Example 1: if url='cnn', it keeps opening new tabs loading cnn. 76 77 Example 2: if urls='amazon,cnn', it keeps opening 78 amazon,cnn,amazon,cnn,amazon,cnn,.... .... 79 """ 80 multiple_tabs: bool = True 81 is_forever: bool = True 82 83 def __iter__(self) -> Iterator[None]: 84 while True: 85 yield None 86 87 88@dataclasses.dataclass(frozen=True) 89class RepeatTabController(TabController): 90 """ 91 Open given urls in separate tabs and repeat for `count` times. 92 93 Example 1: if url='cnn', count=3, it will open 3 tabs: cnn,cnn,cnn. 94 95 Example 2: if urls='amazon,cnn', count=3, it will open 6 tabs: 96 amazon,cnn,amazon,cnn,amazon,cnn 97 """ 98 count: int 99 multiple_tabs: bool = True 100 is_forever: bool = False 101 102 def __iter__(self) -> Iterator[None]: 103 for _ in range(self.count): 104 yield None 105