-
Notifications
You must be signed in to change notification settings - Fork 89
Enable Speedometer to use an external config.json file #515
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 51 commits
Commits
Show all changes
55 commits
Select commit
Hold shift + click to select a range
2747124
initial test
flashdesignory f0f3d93
temp
flashdesignory 43a9646
another checkin
flashdesignory 075f8ff
simplify
flashdesignory be099ff
fix e2e
flashdesignory 0c73ade
fix up stuff
flashdesignory 0c63bc0
fix remote runner
flashdesignory 7d3145b
enable config suite by default
flashdesignory 84983e0
remove console
flashdesignory 17fadf7
changes
flashdesignory bdd87d4
use params
flashdesignory 7c9c69e
rename configUrl to config
flashdesignory 4707d5f
remove Suites and Tags
flashdesignory efb87d2
feedback
flashdesignory 7c724d9
fix e2e config param
flashdesignory fba0a2c
remove console
flashdesignory 4743a1b
fix it up
flashdesignory e6ea8b9
allowlist
flashdesignory 4de58a8
remove comment
flashdesignory 89ca145
run format
flashdesignory 0f511fe
add comment
flashdesignory 6cc6414
cleanup catch in params
flashdesignory 2a85323
rename _containsAllowedUrl to _isAllowedUrl and pass in url directly
flashdesignory 2a03314
add basic validation to the init function
flashdesignory 516d684
simplify suite.disabled assignment
flashdesignory 8c9fd21
simplify suite.disabled assignment p2
flashdesignory 6f8ef3e
rename _suites and _tags params
flashdesignory a807894
cleanup _isAllowedUrl method
flashdesignory 81925af
run format
flashdesignory e701c2d
check readyState
flashdesignory 6f08e6f
run format
flashdesignory 8cd8ccb
add default tag
flashdesignory 0764667
Merge branch 'main' into core/config
flashdesignory 504ccc4
fix default suite in json
flashdesignory b95c47e
import dataProvider in developer-mode
flashdesignory af9d5a4
dynamic import
flashdesignory 7a67c8c
Merge branch 'main' into core/config
flashdesignory 368e9b7
run format
flashdesignory c6075c1
use disallowed domains
flashdesignory 8f7c95b
remove emojis
flashdesignory 113116f
throw error if suite entry is invalid
flashdesignory 890fcb4
validate json url
flashdesignory 289114f
check window location instead of config location
flashdesignory 1d8f45e
add variation
flashdesignory 2e5f751
check variations of domains
flashdesignory b59adc0
run format
flashdesignory 9a37879
rename dataProvider to benchmarkConfigurator
flashdesignory 7e235e5
Merge branch 'main' into core/config
flashdesignory 08af823
re-add dart workload
flashdesignory bcdbe1e
use private vars
flashdesignory eb8c8fa
rename tests.mjs file
flashdesignory 52d10bf
remove json extension check
flashdesignory ad81b73
move multiple declarations into new lines
flashdesignory c010903
add _reportError method
flashdesignory 530759c
remove default tag from config.json
flashdesignory File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
// example url for local testing: | ||
// http://localhost:8080/?config=http://localhost:8080/resources/config.json | ||
import { defaultSuites } from "./default-tests.mjs"; | ||
import { params } from "./shared/params.mjs"; | ||
|
||
const DEFAULT_TAGS = ["all", "default", "experimental"]; | ||
const DISALLOWED_DOMAINS = ["browserbench.org"]; | ||
export class BenchmarkConfigurator { | ||
#tags = new Set(DEFAULT_TAGS); | ||
#suites = []; | ||
|
||
get tags() { | ||
return this.#tags; | ||
} | ||
|
||
get suites() { | ||
return this.#suites; | ||
} | ||
|
||
/** | ||
* Checks if a given string is a valid URL, supporting both absolute and relative paths. | ||
* | ||
* This function attempts to construct a URL object. For relative paths, it uses | ||
* a dummy base URL to allow the URL constructor to parse them successfully. | ||
* | ||
* @param {string} url The URL string to validate. | ||
* @returns {boolean} True if the URL is valid (absolute or relative), false otherwise. | ||
*/ | ||
_isValidUrl(url) { | ||
if (typeof url !== "string" || url.length === 0) | ||
return false; | ||
|
||
try { | ||
new URL(url, "http://www.example.com"); | ||
return true; | ||
} catch (error) { | ||
return false; | ||
} | ||
} | ||
|
||
_freezeSuites() { | ||
Object.freeze(this.#suites); | ||
this.#suites.forEach((suite) => { | ||
if (!suite.tags) | ||
suite.tags = []; | ||
if (suite.url.startsWith("experimental/")) | ||
suite.tags.unshift("all", "experimental"); | ||
else | ||
suite.tags.unshift("all"); | ||
suite.enabled = suite.tags.includes("default"); | ||
Object.freeze(suite.tags); | ||
Object.freeze(suite.steps); | ||
}); | ||
} | ||
|
||
_freezeTags() { | ||
Object.freeze(this.#tags); | ||
} | ||
|
||
async init() { | ||
if (params.config) { | ||
try { | ||
const benchmarkUrl = new URL(window.location); | ||
if (DISALLOWED_DOMAINS.some((domain) => benchmarkUrl.hostname.endsWith(domain))) { | ||
console.warn("Configuration fetch not allowed. Loading default suites."); | ||
this._loadDefaultSuites(); | ||
return; | ||
} | ||
|
||
const response = await fetch(params.config); | ||
|
||
if (!response.ok) | ||
throw new Error(`Could not fetch config: ${response.status}`); | ||
|
||
const config = await response.json(); | ||
|
||
if (!config || !Array.isArray(config.suites)) | ||
throw new Error("Could not find a valid config structure!"); | ||
|
||
config.suites.flatMap((suite) => suite.tags || []).forEach((tag) => this.#tags.add(tag)); | ||
config.suites.forEach((suite) => { | ||
if (suite && suite.url && this._isValidUrl(suite.url)) | ||
this.#suites.push(suite); | ||
else | ||
throw new Error("Invalid suite data"); | ||
}); | ||
} catch (error) { | ||
console.warn(`Error loading custom configuration: ${error.message}. Loading default suites.`); | ||
this._loadDefaultSuites(); | ||
} | ||
} else { | ||
this._loadDefaultSuites(); | ||
} | ||
|
||
this._freezeTags(); | ||
this._freezeSuites(); | ||
} | ||
|
||
_loadDefaultSuites() { | ||
defaultSuites.flatMap((suite) => suite.tags).forEach((tag) => this.#tags.add(tag)); | ||
defaultSuites.forEach((suite) => this.#suites.push(suite)); | ||
} | ||
|
||
enableSuites(names, tags) { | ||
if (names?.length) { | ||
const lowerCaseNames = names.map((each) => each.toLowerCase()); | ||
this.#suites.forEach((suite) => { | ||
suite.enabled = lowerCaseNames.includes(suite.name.toLowerCase()); | ||
}); | ||
} else if (tags?.length) { | ||
tags.forEach((tag) => { | ||
if (!this.#tags.has(tag)) | ||
console.error(`Unknown Suites tag: "${tag}"`); | ||
}); | ||
const tagsSet = new Set(tags); | ||
this.#suites.forEach((suite) => { | ||
suite.enabled = suite.tags.some((tag) => tagsSet.has(tag)); | ||
}); | ||
} else { | ||
console.warn("Neither names nor tags provided. Enabling all default suites."); | ||
this.#suites.forEach((suite) => { | ||
suite.enabled = suite.tags.includes("default"); | ||
}); | ||
} | ||
if (this.#suites.some((suite) => suite.enabled)) | ||
return; | ||
let message, debugInfo; | ||
if (names?.length) { | ||
message = `Suites "${names}" does not match any Suite. No tests to run.`; | ||
debugInfo = { | ||
providedNames: names, | ||
validNames: this.#suites.map((each) => each.name), | ||
}; | ||
} else if (tags?.length) { | ||
message = `Tags "${tags}" does not match any Suite. No tests to run.`; | ||
debugInfo = { | ||
providedTags: tags, | ||
validTags: Array.from(this.#tags), | ||
}; | ||
} | ||
alert(message); | ||
flashdesignory marked this conversation as resolved.
Show resolved
Hide resolved
|
||
console.error(message, debugInfo); | ||
} | ||
} | ||
|
||
const benchmarkConfigurator = new BenchmarkConfigurator(); | ||
await benchmarkConfigurator.init(); | ||
|
||
export { benchmarkConfigurator }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"suites": [ | ||
{ | ||
"name": "NewsSite-PostMessage", | ||
"url": "resources/newssite/news-next/dist/index.html", | ||
"tags": ["default", "newssite", "language"], | ||
flashdesignory marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"type": "remote", | ||
"config": { | ||
"name": "default" | ||
} | ||
} | ||
] | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.