summaryrefslogtreecommitdiffstats
path: root/chromium/tools/browserbench-webdriver/jetstream.py
blob: f4232afecf1e1f01f9a46bd7862726d4cb4c7ce5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# Copyright 2022 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from optparse import OptionParser
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait

import browserbench
import json
import time

URL = 'https://browserbench.org/JetStream/'


# JetStream uses the element 'status' to contain status information.
def _DoesElementHaveClass(driver, element_name, class_value):
  return driver.execute_script(
      'return document.getElementById("%s").classList.contains("%s")' %
      (element_name, class_value))


def _IsLoading(driver):
  return _DoesElementHaveClass(driver, 'status', 'loading')


def _IsDone(driver):
  return _DoesElementHaveClass(driver, 'result-summary', 'done')


def _GetResults(driver, optargs):
  # All benchmarks include a score, but not necessarily a max (and no min). If
  # the max is provided, it is available via subTimes().
  result = json.loads(
      driver.execute_script('''let results = {};
       let allScores = [];
       for (let benchmark of JetStream.benchmarks) {
         allScores.push(benchmark.score);
         results[benchmark.name] = [{
           'value': 'score',
           'measurement': benchmark.score,
         }];
         if (benchmark.subTimes()['Worst']) {
           results[benchmark.name].push({
             'value': 'max',
             'measurement': benchmark.subTimes()['Worst'],
           });
         }
       }
       results['score'] = [{
         'value': 'score',
         'measurement': geomean(allScores),
       }];
       return JSON.stringify(results);'''))
  return result


class JetStream(browserbench.BrowserBench):
  def __init__(self):
    super(JetStream, self).__init__('JetStream')

  def AddExtraParserOptions(self, parser):
    parser.add_option(
        '-s',
        '--suite',
        dest='suite',
        help='Run only the specified suite of tests (comma separated).')

  def RunAndExtractMeasurements(self, driver, optargs):
    driver.get(URL)

    # Jetstream removes the status 'loading' once ready.
    time.sleep(10)
    WebDriverWait(driver,
                  timeout=300).until(lambda driver: not _IsLoading(driver))

    print('no longer loading, about to start')
    # JetStream waits another 4 seconds before starting (add one as 'loading'
    # is removed a bit earlier).
    time.sleep(5)

    if optargs.suite:
      print('running suites', optargs.suite)
      driver.execute_script('JetStream.benchmarks = [];')
      for suite in optargs.suite.split(','):
        driver.execute_script('addTestsByGroup(' + suite + ')')
    else:
      print('running all')

    driver.execute_script('JetStream.start()')

    WebDriverWait(driver, timeout=600).until(lambda driver: _IsDone(driver))
    return _GetResults(driver, optargs)


def main():
  JetStream().Run()


if __name__ == '__main__':
  main()