blob: ab4b33af7979d61542e39918eda9d53df1282bd0 [file] [edit]
#!/usr/bin/env python3
# Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
import os
import shutil
import subprocess
import sys
tools_dir = os.path.dirname(os.path.realpath(__file__))
sys.path.append(tools_dir)
import utils
def run_command(command, cwd, env=None):
print(f"Running: {' '.join(command)} in {cwd}")
if env:
print(f"With environment: {env}")
# TODO(srawlins): Check how to run bash scripts on Windows, or convert the
# devtools scripts to Dart or batch scripts...
# On Windows, if we're running a '.sh' script, we need bash.
if utils.GuessOS() == 'win32' and command[0].endswith('.sh'):
# Assume bash is in PATH (standard for Git for Windows).
command = ['bash'] + command
subprocess.run(command, cwd=cwd, env=env, check=True)
def setup_mac_chrome_symlinks(chrome_bin):
"""Ensure ChromeDriver can discover Chrome on macOS via ~/Applications."""
curr = chrome_bin
app_path = None
while curr and curr != '/':
if curr.endswith('.app'):
app_path = curr
break
curr = os.path.dirname(curr)
if not app_path:
return
user_apps = os.path.expanduser('~/Applications')
try:
os.makedirs(user_apps, exist_ok=True)
except Exception:
return
target = os.path.join(user_apps, 'Google Chrome.app')
try:
if os.path.islink(target) or os.path.isfile(target):
os.unlink(target)
if not os.path.exists(target):
os.symlink(app_path, target)
print(f'Symlinked {target} -> {app_path}')
except Exception as e:
print(f'Warning: Could not create symlink {target} -> {app_path}: {e}')
def find_chrome_executable(sdk_root, platform):
browsers_chrome_dir = os.path.join(sdk_root, 'third_party', 'browsers',
'chrome')
candidates = []
if platform == 'macos':
candidates = [
os.path.join(browsers_chrome_dir, 'Google Chrome.app', 'Contents',
'MacOS', 'Google Chrome'),
'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
]
elif platform == 'linux':
candidates = [
os.path.join(browsers_chrome_dir, 'chrome', 'google-chrome'),
'/usr/bin/google-chrome',
]
for candidate in candidates:
if os.path.isfile(candidate):
return os.path.abspath(candidate)
# Fallback to system PATH for local development machines.
for name in ['google-chrome', 'chrome']:
path = shutil.which(name)
if path:
return os.path.abspath(path)
return None
def main():
host_os = utils.GuessOS()
if host_os == 'win32':
platform = 'windows'
elif host_os == 'macos':
platform = 'macos'
elif host_os == 'linux':
platform = 'linux'
else:
print(f'Unsupported platform: "{host_os}"\n')
return 1
# Set up paths relative to the SDK root.
sdk_root = utils.DART_DIR
devtools_src_dir = os.path.join(sdk_root, 'third_party', 'devtools_src')
if not os.path.isdir(devtools_src_dir):
print(
f'Missing devtools dir in devtools sources "{devtools_src_dir}"; '
'make sure that "../.client" has a `custom_vars` section with '
'"`"build_devtools_from_source": True,` and then run `gclient sync`'
'\n')
return 1
flutter_dir = os.path.normpath(
os.path.join(sdk_root, 'third_party', 'flutter'))
flutter_shell = os.path.join(flutter_dir, 'bin', 'flutter')
if utils.GuessOS() == 'win32':
flutter_shell += '.bat'
if not os.path.isfile(flutter_shell):
print(
f'Missing Flutter SDK at "{flutter_shell}"; '
'make sure that "../.client" has a `custom_vars` section with '
'"`"build_devtools_from_source": True,` and then run `gclient sync`'
'\n')
return 1
env = os.environ.copy()
env['FLUTTER_GIT_URL'] = (
'https://dart.googlesource.com/external/github.com/flutter/flutter.git')
env['DEVTOOLS_TOOL_FLUTTER_FROM_PATH'] = 'true'
if 'RUNNER_OS' not in env:
if platform == 'windows':
env['RUNNER_OS'] = 'Windows'
elif platform == 'macos':
env['RUNNER_OS'] = 'macOS'
else:
env['RUNNER_OS'] = 'Linux'
path_sep = ';' if utils.GuessOS() == 'win32' else ':'
flutter_bin_dir = os.path.join(flutter_dir, 'bin')
env['PATH'] = f"{flutter_bin_dir}{path_sep}{env.get('PATH', '')}"
chromedriver_dir = os.path.join(sdk_root, 'third_party', 'webdriver',
'chrome')
if os.path.isdir(chromedriver_dir):
env['PATH'] = f"{chromedriver_dir}{path_sep}{env.get('PATH', '')}"
chrome_bin = find_chrome_executable(sdk_root, platform)
if chrome_bin:
print(f'Using Chrome executable: {chrome_bin}')
env['CHROME_EXECUTABLE'] = chrome_bin
env['CHROME_PATH'] = chrome_bin
chrome_dir = os.path.dirname(chrome_bin)
env['PATH'] = f"{chrome_dir}{path_sep}{env.get('PATH', '')}"
if platform == 'macos':
setup_mac_chrome_symlinks(chrome_bin)
else:
print('Warning: Chrome executable not found; web tests may fail.')
jobs = []
if platform in ['linux', 'windows']:
jobs.append({'script': 'tool/ci/bots.sh', 'env': {'BOT': 'main'}})
for pkg in [
'devtools_app_shared',
'devtools_extensions',
'devtools_shared',
]:
# TODO(srawlins): Enable devtools_extensions integration tests.
if platform == 'windows':
print('DevTools tests are currently skipped on Windows.')
return 0
jobs.append({
'script': 'tool/ci/package_tests.sh',
'env': {
'PACKAGE': pkg
}
})
jobs.append({'script': 'tool/ci/tool_tests.sh', 'env': {}})
for bot in ['build_ddc', 'build_dart2js', 'test_ddc']:
jobs.append({
'script': 'tool/ci/bots.sh',
'env': {
'BOT': bot,
'PLATFORM': 'vm'
}
})
test_dart2js_env = {
'BOT': 'test_dart2js',
'PLATFORM': 'vm',
}
if platform == 'macos':
test_dart2js_env['ONLY_GOLDEN'] = 'true'
jobs.append({
'script': 'tool/ci/bots.sh',
'env': test_dart2js_env,
})
if platform == 'macos':
for bot in ['integration_dart2js', 'integration_dart2wasm']:
for device in ['flutter', 'flutter-web', 'dart-cli']:
jobs.append({
'script': 'tool/ci/bots.sh',
'env': {
'BOT': bot,
'DEVICE': device,
'DEVTOOLS_PACKAGE': 'devtools_app'
}
})
# TODO(srawlins): Enable devtools_extensions integration tests.
# if platform in ['linux', 'windows']:
# for bot in ['integration_dart2js', 'integration_dart2wasm']:
# jobs.append({
# 'script': 'tool/ci/bots.sh',
# 'env': {
# 'BOT': bot,
# 'DEVTOOLS_PACKAGE': 'devtools_extensions'
# }
# })
jobs.append({
'script': 'tool/ci/bots.sh',
'env': {
'BOT': 'test_webdriver',
'PLATFORM': 'vm'
}
})
if platform == 'linux':
jobs.append({'script': 'tool/ci/benchmark_size.sh', 'env': {}})
# TODO(srawlins): Enable benchmark_performance tests.
# if platform == 'macos':
# jobs.append({'script': 'tool/ci/benchmark_performance.sh', 'env': {}})
for i, job in enumerate(jobs):
print(
f"\nJob {i+1}/{len(jobs)}: {job['env'] if job['env'] else job['script']}"
)
try:
job_env = env.copy()
if job.get('env'):
job_env.update(job['env'])
run_command(['./' + job['script']],
cwd=devtools_src_dir,
env=job_env)
except subprocess.CalledProcessError as e:
print(f'Error: Job failed with exit code {e.returncode}')
return e.returncode
except Exception as e:
print(f'An unexpected error occurred: {e}')
return 1
print(f"\nAll DevTools tests for {platform} completed successfully.")
return 0
if __name__ == '__main__':
sys.exit(main())