1 | {"version":3,"file":"resolveEnvironments.js","sourceRoot":"","sources":["../../../src/lib/resolveEnvironments.ts"],"names":[],"mappings":"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","sourcesContent":["import { EnvironmentSpec } from './common/config';\nimport { NormalizedEnvironment } from '@theintern/digdug/Tunnel';\nimport { normalize } from 'path';\n\nimport process from './node/process';\n\n/**\n * Resolves a collection of Intern test environments to a list of service\n * environments\n *\n * @param capabilities a base set of capabilities for all environments\n * @param environments a list of user-requested enviromnents\n * @param available a list of available environments\n * @returns a list of flattened service environments\n */\nexport default function resolveEnvironments(\n capabilities: { [key: string]: any },\n environments: EnvironmentOptions[],\n available?: NormalizedEnvironment[]\n): EnvironmentSpec[] {\n // Pre-process the environments list to resolve any uses of {pwd} and do any\n // top-level substitutions\n environments = environments.map(expandPwd);\n\n // Update the browserName to match the target environment (only relevant for\n // edge / MicrosoftEdge)\n if (available) {\n environments = normalizeBrowserNames(environments, available);\n }\n\n // flatEnviroments will have non-array versions\n const flatEnvironments = createPermutations(capabilities, environments);\n\n // Expand any version ranges or aliases in the environments.\n const expandedEnvironments = flatEnvironments.map(function(environment) {\n const browserVersion = resolveVersions(environment, available);\n if (browserVersion == null) {\n return environment;\n }\n return {\n ...environment,\n browserVersion,\n version: browserVersion\n };\n });\n\n // Perform a second round of permuting to handle any expanded version ranges\n return createPermutations({}, expandedEnvironments).map(normalizeEnvironment);\n}\n\nexport interface EnvironmentOptions {\n browserName: string | string[];\n version?: string | string[] | number | number[];\n [key: string]: any;\n}\n\nexport interface FlatEnvironment {\n browserName: string;\n version?: string;\n [key: string]: any;\n}\n\n/**\n * Expands {pwd} placeholders in a value. The value is assumed to be a string,\n * simple object, or array of strings or simple objects.\n */\nfunction expandPwd<T>(value: T): T {\n if (value == null) {\n return value;\n }\n\n if (typeof value === 'string' && /{pwd}/.test(value)) {\n return <any>normalize(value.replace(/{pwd}/g, process.cwd()));\n }\n\n if (Array.isArray(value)) {\n return <any>value.map(expandPwd);\n }\n\n if (typeof value === 'object') {\n return <any>Object.keys(value).reduce(\n (newObj, key) => ({\n ...newObj,\n [key]: expandPwd((<any>value)[key])\n }),\n {}\n );\n }\n\n return value;\n}\n\n/**\n * Ensure environment has both `version` and `browserVersion` properties with\n * the same value\n */\nfunction normalizeEnvironment(env: EnvironmentOptions) {\n const normEnv = { ...env };\n const browserVersion = env.browserVersion || env.version;\n\n if (browserVersion != null) {\n normEnv.version = browserVersion;\n normEnv.browserVersion = browserVersion;\n }\n\n const browserName = env.browserName || env.browser;\n normEnv.browser = browserName;\n normEnv.browserName = browserName;\n\n return normEnv as EnvironmentSpec;\n}\n\n/**\n * Expands a range of versions using available environments\n */\nfunction expandVersionRange(\n left: string,\n right: string,\n availableVersions: string[]\n) {\n if (\n availableVersions.indexOf(left) === -1 ||\n availableVersions.indexOf(right) === -1\n ) {\n throw new Error(\n 'The version range ' + left + '..' + right + ' is unavailable'\n );\n }\n return availableVersions.filter(function(version) {\n return version >= left && version <= right;\n });\n}\n\n/**\n * Resolves a version alias from a list of available versions.\n *\n * Assumes availableVersions is sorted in ascending order. Acceptable versions\n * are:\n *\n * * '{number}'\n * * 'latest'\n * * 'latest-{number}'\n */\nfunction resolveVersionAlias(version: string, availableVersions: string[]) {\n // The version 'insider preview' is used for Edge Chromium (at least until\n // it's officially released).\n if (version === 'insider preview') {\n // If there are available versions and 'insider preview' isn't one of them,\n // throw an error. If there are no available versions, assume we're running\n // on a local Selenium server so the version doesn't matter.\n if (\n availableVersions.length > 0 &&\n availableVersions.indexOf(version) === -1\n ) {\n throw new Error(`\"${version}\" is not available`);\n }\n return version;\n }\n\n let pieces = version.split('-');\n if (pieces.length > 2) {\n throw new Error('Invalid alias syntax \"' + version + '\"');\n }\n\n pieces = pieces.map(function(piece) {\n return piece.trim();\n });\n\n if (\n (pieces.length === 2 &&\n (pieces[0] !== 'latest' || isNaN(Number(pieces[1])))) ||\n (pieces.length === 1 && isNaN(Number(pieces[0])) && pieces[0] !== 'latest')\n ) {\n throw new Error('Invalid alias syntax \"' + version + '\"');\n }\n\n if (pieces[0] === 'latest') {\n // Only consider numeric versions; we don't want 'beta' or 'dev'\n const numericVersions = availableVersions\n .filter(version => !isNaN(Number(version)))\n .sort((a, b) => Number(a) - Number(b));\n\n let offset = pieces.length === 2 ? Number(pieces[1]) : 0;\n if (offset > numericVersions.length) {\n throw new Error(\n `Can't get ${version}; ${numericVersions.length} version${\n numericVersions.length !== 1 ? 's are' : ' is'\n } available`\n );\n }\n\n return numericVersions[numericVersions.length - 1 - offset];\n } else {\n return pieces[0];\n }\n}\n\n/**\n * Splits a version into one or two version strings using the '..' delimiter\n *\n * @returns {string[]}\n */\nfunction splitVersions(versionSpec: string) {\n const versions = versionSpec.split('..');\n\n if (versions.length > 2) {\n throw new Error('Invalid version syntax');\n }\n\n return versions.map(function(version) {\n return version.trim();\n });\n}\n\n/**\n * Get a list of versions from a list of available environments filtered by the\n * current environment.\n *\n * @param environment the environment for which versions should match\n * @param available a list of available environments\n * @returns a list of version numbers from available filtered by the current\n * environment\n */\nfunction getVersions(\n environment: EnvironmentOptions,\n available: NormalizedEnvironment[]\n): string[] {\n let versions: { [key: string]: boolean } = {};\n\n available\n .filter(function(availableEnvironment) {\n // Return true if there are no mismatching keys\n return !Object.keys(environment)\n // Don't match on version since we want all the available versions where\n // all the other keys match. Don't match 'browser' since we'll always\n // have 'browserName'.\n .filter(\n key =>\n key === 'browserName' ||\n key === 'platformName' ||\n key === 'platform' ||\n key === 'platformVersion'\n )\n .some(envKey => {\n const key = <keyof NormalizedEnvironment>envKey;\n if (!(key in availableEnvironment)) {\n return false;\n }\n\n let value = environment[key];\n if (typeof value === 'string') {\n value = value.toLowerCase();\n }\n\n let availableValue = availableEnvironment[key];\n if (typeof availableValue === 'string') {\n availableValue = availableValue.toLowerCase();\n }\n\n // At least BrowserStack uses 'edge' for MicrosoftEdge, while everyone\n // else + the Edge webdrivers use 'MicrosoftEdge'.\n if (key === 'browserName' && value === 'microsoftedge') {\n return (\n availableValue !== 'microsoftedge' || availableValue !== 'edge'\n );\n }\n\n return availableValue !== value;\n });\n })\n .forEach(function(availableEnvironment) {\n versions[availableEnvironment.version] = true;\n });\n\n return Object.keys(versions).sort((a, b) => {\n const na = Number(a);\n const nb = Number(b);\n if (!isNaN(na) && !isNaN(nb)) {\n return na - nb;\n }\n if (a < b) {\n return -1;\n }\n if (a > b) {\n return 1;\n }\n return 0;\n });\n}\n\n/**\n * Resolves version aliases (e.g. latest, latest - 1) and version ranges (e.g.\n * 36 .. latest or latest - 3 .. latest) using the environment list returned by\n * tunnel#getEnvironments().\n *\n * @param environment an object with an optional version property\n * @param available a list of environment available on the target service\n * @returns the environment with resolved version aliases\n */\nfunction resolveVersions(\n environment: FlatEnvironment,\n available?: NormalizedEnvironment[]\n): string | string[] | undefined {\n let versionSpec = environment.version;\n let versions: string[];\n available = available || [];\n\n if (versionSpec && isNaN(Number(versionSpec))) {\n let availableVersions = getVersions(environment, available);\n\n versions = splitVersions(versionSpec).map(function(version) {\n const resolved = resolveVersionAlias(version, availableVersions);\n if (resolved == null) {\n throw new Error(\n `Unable to resolve version \"${version}\" for ${\n environment.browserName\n }. Are you using the proper browser and platform names for the tunnel?`\n );\n }\n return resolved;\n });\n\n if (versions.length === 2) {\n if (\n versions[0] === 'insider preview' ||\n versions[1] === 'insider preview'\n ) {\n throw new Error('\"insider preview\" cannot be used in a version range');\n }\n\n if (versions[0] > versions[1]) {\n throw new Error(\n 'Invalid range [' + versions + '], must be in ascending order'\n );\n }\n\n versions = expandVersionRange(\n versions[0],\n versions[1],\n availableVersions\n );\n }\n\n return versions;\n }\n\n return versionSpec;\n}\n\n/**\n * Builds permutations of an object by flattening properties holding array\n * values into a collection of objects representing all combinations of objects\n * for all arrays in the object.\n *\n * @param base a base set of properties applied to each source\n * @param sources a list of sources to flatten\n * @return a flattened collection of sources\n */\nfunction createPermutations(\n base: { [key: string]: string },\n sources?: EnvironmentOptions[]\n): FlatEnvironment[] {\n // If no expansion sources were given, the set of permutations consists of\n // just the base\n if (!sources || sources.length === 0) {\n return [<FlatEnvironment>{ ...base }];\n }\n\n // Expand the permutation set for each source\n return sources\n .map(function(source) {\n return Object.keys(source).reduce(\n (permutations: FlatEnvironment[], key: string) => {\n if (Array.isArray(source[key])) {\n // For array values, create a copy of the permutation\n // set for each array item, then use the combination of\n // these copies as the new value of `permutations`\n permutations = source[key]\n .map((value: any) =>\n permutations.map(permutation => ({\n ...permutation,\n [key]: value\n }))\n )\n .reduce(\n (newPermutations: object[], keyPermutations: object[]) =>\n newPermutations.concat(keyPermutations),\n []\n );\n } else {\n // For simple values, add the value to all current\n // permutations\n permutations.forEach(permutation => {\n permutation[key] = source[key];\n });\n }\n return permutations;\n },\n [<FlatEnvironment>{ ...base }]\n );\n })\n .reduce(\n (newPermutations, sourcePermutations) =>\n newPermutations.concat(sourcePermutations),\n []\n );\n}\n\nfunction normalizeBrowserNames(\n environments: EnvironmentOptions[],\n available: NormalizedEnvironment[]\n) {\n return environments.map(env => {\n if (env.browserName === 'MicrosoftEdge') {\n if (available.some(ae => ae.browserName === 'edge')) {\n return {\n ...env,\n browserName: 'edge'\n };\n }\n }\n return env;\n });\n}\n"]} |