diff --git a/.github/actions/before-e2e/action.yml b/.github/actions/before-e2e/action.yml index 1f7e63ba3..f7049dc1c 100644 --- a/.github/actions/before-e2e/action.yml +++ b/.github/actions/before-e2e/action.yml @@ -1,6 +1,13 @@ name: "Before e2e" description: "Before e2e" +inputs: + e2e-protractor: + description: 'is e2e run with protractor' + required: false + type: boolean + default: false + runs: using: "composite" steps: @@ -8,23 +15,16 @@ runs: shell: bash run: ./node_modules/@alfresco/adf-cli/bin/adf-cli check-cs-env --host $BASE_URL -u $ADMIN_EMAIL -p $ADMIN_PASSWORD || exit 1 - - name: Install google chrome + - name: Install google chrome v114 shell: bash run: | - wget -q https://mirror.cs.uchicago.edu/google-chrome/pool/main/g/google-chrome-stable/google-chrome-stable_114.0.5735.106-1_amd64.deb - sudo apt install -y --allow-downgrades ./google-chrome-stable_114.0.5735.106-1_amd64.deb + wget -q https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb + sudo apt install ./google-chrome-stable_current_amd64.deb sudo ln -s /usr/bin/google-chrome /usr/bin/chrome chrome --version - name: Update webdriver-manager + if: ${{ inputs.e2e-protractor == 'true' }} shell: bash run: | - npm install -g webdriver-manager - if [ "$CI" = "true" ]; then - export chrome=$(google-chrome --product-version) - echo "Updating wevdriver-manager with chromedriver: $chrome." - webdriver-manager update --gecko=false --versions.chrome=$chrome - else - echo "Updating wedriver-manager with latest chromedriver, be sure to use evergreen Chrome." - webdriver-manager update --gecko=false - fi + npm run update-webdriver diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 3b08eff07..36852daf0 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -129,7 +129,10 @@ jobs: path: ./dist/content-ce key: cache-dist-${{ github.run_id }} - - uses: ./.github/actions/before-e2e + - name: Before e2e + uses: ./.github/actions/before-e2e + with: + e2e-protractor: true - uses: ./.github/actions/run-e2e with: @@ -194,7 +197,10 @@ jobs: path: ./dist/content-ce key: cache-dist-${{ github.run_id }} - - uses: ./.github/actions/before-e2e + - name: Before e2e + uses: ./.github/actions/before-e2e + with: + e2e-protractor: false - name: before playwright shell: bash diff --git a/package.json b/package.json index 950f41087..3b1eaef1a 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "build.release": "npm run build -- --configuration=production,release", "test": "nx test", "lint": "NODE_OPTIONS=--max_old_space_size=4096 nx run-many --all --target=lint", - "update-webdriver": "./scripts/update-webdriver.sh", + "update-webdriver": "./scripts/webdriver-update-newest/update-to-newest-webdriver.sh", "e2e": "npm run update-webdriver && protractor $SUITE", "inspect.bundle": "nx build content-ce --configuration production --stats-json && npx webpack-bundle-analyzer dist/content-ce/stats.json", "prepare": "husky install", diff --git a/scripts/update-webdriver.sh b/scripts/update-webdriver.sh deleted file mode 100755 index a1ff5e7c6..000000000 --- a/scripts/update-webdriver.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - -if [ "$CI" = "true" ]; then - echo "Updating wedriver-manager with chromedriver: $npm_package_config_chromeDriver." - ./node_modules/protractor/bin/webdriver-manager update --gecko=false --versions.chrome=83.0.4103.116 -else - echo "Updating wedriver-manager with latest chromedriver, be sure to use evergreen Chrome." - ./node_modules/protractor/bin/webdriver-manager update --gecko=false -fi diff --git a/scripts/webdriver-update-newest/README.md b/scripts/webdriver-update-newest/README.md new file mode 100644 index 000000000..80a38ef3d --- /dev/null +++ b/scripts/webdriver-update-newest/README.md @@ -0,0 +1,37 @@ +# Run protractor with newest webdriver locally + +## Instruction +To download newest driver simply run script from its directory +`update-to-newest-webdriver.sh` + +Command accepts one parameter to define what OS you are using. By default its set to `mac-x64` +Possible inputs `linux64, mac-arm64, mac-x64, win32, win64` + +Example `./update-to-newest-webdriver.sh win64` - will set driver for windows + +## How it works +1. The script removes your existing driver files from webdriver node_modules +2. Generates two new files (chrome_xml.js and update.js) that have updated methods needed to get the new driver +3. Replaces browser type depending on parameter +4. Copies and replaces the files to the webdriver node_modules +5. Executes command to to update-webdriver using updated code + +## Troubleshooting +If the script fails for any reason. You can do some of these actions manually: +1. Find the two files (chrome_xml.js and update.js) in node_modules/webdriver-manager +2. Replace its contents with (chrome_xml_schema.js and update_schema.js) keep the original names. +3. Change version for specific OS in both files + chrome_xml.js -> ['platform'] == 'mac-x64' e.g. ['platform'] == 'win64' Line 70 + update.js -> 'chromedriver-mac-x64' e.g 'chromedriver-win64' Line 240 +4. Run standard command to update webdriver `./node_modules/webdriver-manager/bin/webdriver-manager update --gecko=false` + + + +## Reason +Latest ChromeDriver Binaries https://googlechromelabs.github.io/chrome-for-testing/ + +Starting with M115 the latest Chrome + ChromeDriver releases per release channel (Stable, Beta, Dev, Canary) are available at the Chrome for Testing availability dashboard. For automated version downloading one can use the convenient JSON endpoints. +The older releases can be found at the Downloads page. + + +Note: Protractor is a depricated tool and this probably won't be fixed. \ No newline at end of file diff --git a/scripts/webdriver-update-newest/chrome_xml_schema.js b/scripts/webdriver-update-newest/chrome_xml_schema.js new file mode 100644 index 000000000..5f33d056b --- /dev/null +++ b/scripts/webdriver-update-newest/chrome_xml_schema.js @@ -0,0 +1,181 @@ +'use strict'; +Object.defineProperty(exports, '__esModule', { value: true }); +const semver = require('semver'); +const config_1 = require('../config'); +const http_utils_1 = require('../http_utils'); +const config_source_1 = require('./config_source'); +class ChromeXml extends config_source_1.XmlConfigSource { + constructor() { + super('chrome', config_1.Config.cdnUrls()['chrome']); + this.maxVersion = config_1.Config.binaryVersions().maxChrome; + } + getUrl(version) { + if (version === 'latest') { + return this.getLatestChromeDriverVersion(); + } else { + return this.getSpecificChromeDriverVersion(version); + } + } + /** + * Get a list of chrome drivers paths available for the configuration OS type and architecture. + */ + getVersionList() { + return this.getXml().then((xml) => { + let versionPaths = []; + let osType = this.getOsTypeName(); + for (let content of xml.ListBucketResult.Contents) { + let contentKey = content.Key[0]; + if ( + // Filter for 32-bit devices, make sure x64 is not an option + (this.osarch.includes('64') || !contentKey.includes('64')) && + // Filter for x86 macs, make sure m1 is not an option + ((this.ostype === 'Darwin' && this.osarch === 'arm64') || !contentKey.includes('m1')) + ) { + // Filter for only the osType + if (contentKey.includes(osType)) { + versionPaths.push(contentKey); + } + } + } + return versionPaths; + }); + } + /** + * Helper method, gets the ostype and gets the name used by the XML + */ + getOsTypeName() { + // Get the os type name. + if (this.ostype === 'Darwin') { + return 'mac-x64'; + } else if (this.ostype === 'Windows_NT') { + return 'win64'; + } else { + return 'linux64'; + } + } + /** + * Gets the latest item from the XML. + */ + getLatestChromeDriverVersion() { + const path = require('path'); + const fs = require('fs'); + + const lastKnownGoodVersionsWithDownloads_Url = + 'https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json'; + return http_utils_1.requestBody(lastKnownGoodVersionsWithDownloads_Url).then((body) => { + const latestVersion_Body = JSON.parse(body)['channels']['Stable']; + + const latestVersion = latestVersion_Body['version']; + const latestVersion_Url = latestVersion_Body['downloads']['chromedriver'].find((obj) => obj['platform'] == 'mac-x64')['url']; + + const latestMajorVersion = latestVersion.split('.')[0]; + + const localVersion_FileName = + fs + .readdirSync(path.resolve(__dirname, '..', '..', '..', 'selenium')) + .find((f) => f.startsWith(`chromedriver_${latestMajorVersion}`)) || ''; + + const localVersion = localVersion_FileName.slice(13, -4); + const localVersion_Url = latestVersion_Url.replace(latestVersion, localVersion); + + const localMajorVersion = localVersion.split('.')[0]; + + if (latestMajorVersion == localMajorVersion) { + return Promise.resolve({ + url: localVersion_Url, + version: localVersion + }); + } else { + return Promise.resolve({ + url: latestVersion_Url, + version: latestVersion + }); + } + }); + } + /** + * Gets a specific item from the XML. + */ + getSpecificChromeDriverVersion(versionRequired) { + const path = require('path'); + const fs = require('fs'); + + let baseTagVersion = versionRequired.split('.'); + baseTagVersion.splice(-1); + baseTagVersion = baseTagVersion.join('.'); + + const lastKnownGoodVersionsWithDownloads_Url = + 'https://googlechromelabs.github.io/chrome-for-testing/latest-patch-versions-per-build-with-downloads.json'; + return http_utils_1.requestBody(lastKnownGoodVersionsWithDownloads_Url).then((body) => { + const version_Body = JSON.parse(body)['builds'][baseTagVersion]; + + const opSys = this.getOsTypeName(); + + const currentVersion = version_Body['version']; + const currentVersion_Url = version_Body['downloads']['chromedriver'].find((obj) => obj['platform'] == opSys)['url']; + + const latestMajorVersion = currentVersion.split('.')[0]; + + const localVersion_FileName = + fs + .readdirSync(path.resolve(__dirname, '..', '..', '..', 'selenium')) + .find((f) => f.startsWith(`chromedriver_${latestMajorVersion}`)) || ''; + + const localVersion = localVersion_FileName.slice(13, -4); + const localVersion_Url = currentVersion_Url.replace(currentVersion, localVersion); + + const localMajorVersion = localVersion.split('.')[0]; + + if (latestMajorVersion == localMajorVersion) { + return Promise.resolve({ + url: localVersion_Url, + version: localVersion + }); + } else { + return Promise.resolve({ + url: currentVersion_Url, + version: currentVersion + }); + } + }); + } +} +exports.ChromeXml = ChromeXml; +/** + * Chromedriver is the only binary that does not conform to semantic versioning + * and either has too little number of digits or too many. To get this to be in + * semver, we will either add a '.0' at the end or chop off the last set of + * digits. This is so we can compare to find the latest and greatest. + * + * Example: + * 2.46 -> 2.46.0 + * 75.0.3770.8 -> 75.0.3770 + * + * @param version + */ +function getValidSemver(version) { + let lookUpVersion = ''; + // This supports downloading 2.46 + try { + const oldRegex = /(\d+.\d+)/g; + const exec = oldRegex.exec(version); + if (exec) { + lookUpVersion = exec[1] + '.0'; + } + } catch (_) { + // no-op: is this is not valid, do not throw here. + } + // This supports downloading 74.0.3729.6 + try { + const newRegex = /(\d+.\d+.\d+).\d+/g; + const exec = newRegex.exec(version); + if (exec) { + lookUpVersion = exec[1]; + } + } catch (_) { + // no-op: if this does not work, use the other regex pattern. + } + return lookUpVersion; +} +exports.getValidSemver = getValidSemver; +//# sourceMappingURL=chrome_xml.js.map diff --git a/scripts/webdriver-update-newest/update-to-newest-webdriver.sh b/scripts/webdriver-update-newest/update-to-newest-webdriver.sh new file mode 100755 index 000000000..979b3029c --- /dev/null +++ b/scripts/webdriver-update-newest/update-to-newest-webdriver.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +echo "Getting currently installed Chrome Version" + +if [ "$CI" = "true" ]; then + chromeVersion=$(google-chrome --version ) +else + chromeVersion=$(/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --version ) +fi + +chromeVersion=${chromeVersion:14:20} + +echo "Intalling webdriver for version: $chromeVersion" + +function show_error() { + echo -e "\e[31m===============================================================\e[0m" + echo -e "\e[31mFAILED TO UPDATE WEBDRIVER-MANAGER, PLEASE DO IT MANUALLY!\e[0m" + echo -e "\e[31mRun the following command (sometimes needs more than one kick):\e[0m" + echo -e "" + echo -e "\e[31mnpx webdriver-manager update --gecko=false\e[0m" + echo -e "" + echo -e "\e[31m===============================================================\e[0m" +} + +ROOTDIR="$DIR/.." + +if [ "$(uname)" == "Darwin" ]; then + BROWSER_TYPE="mac-x64" +elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then + BROWSER_TYPE="linux64" +elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW32_NT" ]; then + BROWSER_TYPE="win32" +elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW64_NT" ]; then + BROWSER_TYPE="win64" +fi + +echo "BROWSER => $BROWSER_TYPE" + + +PATH_TO_COMMANDS=./node_modules/webdriver-manager/built/lib/cmds +PATH_TO_BINARIES=./node_modules/webdriver-manager/built/lib/binaries +PATH_TO_SELENIUM=./node_modules/webdriver-manager/selenium + +# Remove existing drivers +rm -rf $PATH_TO_SELENIUM/selenium-server-* +rm -rf $PATH_TO_SELENIUM/chromedriver-* +rm -f $PATH_TO_SELENIUM/chromedriver_* + +# Replace browser type in file and create new file +echo 'Replacing new webdriver files' +sed "s/mac-x64/$BROWSER_TYPE/" $DIR/chrome_xml_schema.js > $DIR/chrome_xml.js && sed "s/mac-x64/$BROWSER_TYPE/" $DIR/update_schema.js > $DIR/update.js; + +if [ "$?" -ne 0 ]; then + show_error + exit 0 +fi + +echo "============== Trying to update the files ==============" +sleep 2 + +# Replace webdriver files +echo "cp -f $DIR/update.js $PATH_TO_COMMANDS/update.js" +cp -f $DIR/update.js $PATH_TO_COMMANDS/update.js +cp -f $DIR/chrome_xml.js $PATH_TO_BINARIES/chrome_xml.js + +rm -f $DIR/update.js +rm -f $DIR/chrome_xml.js + +node ./node_modules/webdriver-manager/bin/webdriver-manager update --gecko=false --versions.chrome=$chromeVersion + + diff --git a/scripts/webdriver-update-newest/update_schema.js b/scripts/webdriver-update-newest/update_schema.js new file mode 100644 index 000000000..942097d10 --- /dev/null +++ b/scripts/webdriver-update-newest/update_schema.js @@ -0,0 +1,304 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const AdmZip = require("adm-zip"); +const child_process = require("child_process"); +const fs = require("fs"); +const minimist = require("minimist"); +const path = require("path"); +const q = require("q"); +const rimraf = require("rimraf"); +const binaries_1 = require("../binaries"); +const cli_1 = require("../cli"); +const config_1 = require("../config"); +const files_1 = require("../files"); +const http_utils_1 = require("../http_utils"); +const utils_1 = require("../utils"); +const Opt = require("./"); +const initialize_1 = require("./initialize"); +const opts_1 = require("./opts"); +config_1.Config.runCommand = 'update'; +let logger = new cli_1.Logger('update'); +let prog = new cli_1.Program() + .command('update', 'install or update selected binaries') + .action(update) + .addOption(opts_1.Opts[Opt.OUT_DIR]) + .addOption(opts_1.Opts[Opt.VERBOSE]) + .addOption(opts_1.Opts[Opt.IGNORE_SSL]) + .addOption(opts_1.Opts[Opt.PROXY]) + .addOption(opts_1.Opts[Opt.ALTERNATE_CDN]) + .addOption(opts_1.Opts[Opt.STANDALONE]) + .addOption(opts_1.Opts[Opt.CHROME]) + .addOption(opts_1.Opts[Opt.GECKO]) + .addOption(opts_1.Opts[Opt.ANDROID]) + .addOption(opts_1.Opts[Opt.ANDROID_API_LEVELS]) + .addOption(opts_1.Opts[Opt.ANDROID_ARCHITECTURES]) + .addOption(opts_1.Opts[Opt.ANDROID_PLATFORMS]) + .addOption(opts_1.Opts[Opt.ANDROID_ACCEPT_LICENSES]); +if (config_1.Config.osType() === 'Darwin') { + prog.addOption(opts_1.Opts[Opt.IOS]); +} +if (config_1.Config.osType() === 'Windows_NT') { + prog.addOption(opts_1.Opts[Opt.IE]).addOption(opts_1.Opts[Opt.IE32]).addOption(opts_1.Opts[Opt.IE64]); +} +prog.addOption(opts_1.Opts[Opt.VERSIONS_STANDALONE]) + .addOption(opts_1.Opts[Opt.VERSIONS_CHROME]) + .addOption(opts_1.Opts[Opt.VERSIONS_APPIUM]) + .addOption(opts_1.Opts[Opt.VERSIONS_ANDROID]) + .addOption(opts_1.Opts[Opt.VERSIONS_GECKO]); +if (config_1.Config.osType() === 'Windows_NT') { + prog.addOption(opts_1.Opts[Opt.VERSIONS_IE]); +} +exports.program = prog; +// stand alone runner +let argv = minimist(process.argv.slice(2), prog.getMinimistOptions()); +if (argv._[0] === 'update-run') { + prog.run(JSON.parse(JSON.stringify(argv))); +} +else if (argv._[0] === 'update-help') { + prog.printHelp(); +} +let browserFile; +/** + * Parses the options and downloads binaries if they do not exist. + * @param options + */ +function update(options) { + let promises = []; + let standalone = options[Opt.STANDALONE].getBoolean(); + let chrome = options[Opt.CHROME].getBoolean(); + let gecko = options[Opt.GECKO].getBoolean(); + let ie32 = false; + let ie64 = false; + if (options[Opt.IE]) { + ie32 = ie32 || options[Opt.IE].getBoolean(); + } + if (options[Opt.IE32]) { + ie32 = ie32 || options[Opt.IE32].getBoolean(); + } + if (options[Opt.IE64]) { + ie64 = options[Opt.IE64].getBoolean(); + } + let android = options[Opt.ANDROID].getBoolean(); + let ios = false; + if (options[Opt.IOS]) { + ios = options[Opt.IOS].getBoolean(); + } + let outputDir = options[Opt.OUT_DIR].getString(); + try { + browserFile = + JSON.parse(fs.readFileSync(path.resolve(outputDir, 'update-config.json')).toString()); + } + catch (err) { + browserFile = {}; + } + let android_api_levels = options[Opt.ANDROID_API_LEVELS].getString().split(','); + let android_architectures = options[Opt.ANDROID_ARCHITECTURES].getString().split(','); + let android_platforms = options[Opt.ANDROID_PLATFORMS].getString().split(','); + let android_accept_licenses = options[Opt.ANDROID_ACCEPT_LICENSES].getBoolean(); + if (options[Opt.OUT_DIR].getString()) { + if (path.isAbsolute(options[Opt.OUT_DIR].getString())) { + outputDir = options[Opt.OUT_DIR].getString(); + } + else { + outputDir = path.resolve(config_1.Config.getBaseDir(), options[Opt.OUT_DIR].getString()); + } + files_1.FileManager.makeOutputDirectory(outputDir); + } + let ignoreSSL = options[Opt.IGNORE_SSL].getBoolean(); + let proxy = options[Opt.PROXY].getString(); + http_utils_1.HttpUtils.assignOptions({ ignoreSSL, proxy }); + let verbose = options[Opt.VERBOSE].getBoolean(); + // setup versions for binaries + let binaries = files_1.FileManager.setupBinaries(options[Opt.ALTERNATE_CDN].getString()); + binaries[binaries_1.Standalone.id].versionCustom = options[Opt.VERSIONS_STANDALONE].getString(); + binaries[binaries_1.ChromeDriver.id].versionCustom = options[Opt.VERSIONS_CHROME].getString(); + if (options[Opt.VERSIONS_IE]) { + binaries[binaries_1.IEDriver.id].versionCustom = options[Opt.VERSIONS_IE].getString(); + } + if (options[Opt.VERSIONS_GECKO]) { + binaries[binaries_1.GeckoDriver.id].versionCustom = options[Opt.VERSIONS_GECKO].getString(); + } + binaries[binaries_1.AndroidSDK.id].versionCustom = options[Opt.VERSIONS_ANDROID].getString(); + binaries[binaries_1.Appium.id].versionCustom = options[Opt.VERSIONS_APPIUM].getString(); + // if the file has not been completely downloaded, download it + // else if the file has already been downloaded, unzip the file, rename it, and give it + // permissions + if (standalone) { + let binary = binaries[binaries_1.Standalone.id]; + promises.push(files_1.FileManager.downloadFile(binary, outputDir) + .then((downloaded) => { + if (!downloaded) { + logger.info(binary.name + ': file exists ' + + path.resolve(outputDir, binary.filename())); + logger.info(binary.name + ': ' + binary.filename() + ' up to date'); + } + }) + .then(() => { + updateBrowserFile(binary, outputDir); + })); + } + if (chrome) { + let binary = binaries[binaries_1.ChromeDriver.id]; + promises.push(updateBinary(binary, outputDir, proxy, ignoreSSL).then(() => { + return Promise.resolve(updateBrowserFile(binary, outputDir)); + })); + } + if (gecko) { + let binary = binaries[binaries_1.GeckoDriver.id]; + promises.push(updateBinary(binary, outputDir, proxy, ignoreSSL).then(() => { + return Promise.resolve(updateBrowserFile(binary, outputDir)); + })); + } + if (ie64) { + let binary = binaries[binaries_1.IEDriver.id]; + binary.osarch = config_1.Config.osArch(); // Win32 or x64 + promises.push(updateBinary(binary, outputDir, proxy, ignoreSSL).then(() => { + return Promise.resolve(updateBrowserFile(binary, outputDir)); + })); + } + if (ie32) { + let binary = binaries[binaries_1.IEDriver.id]; + binary.osarch = 'Win32'; + promises.push(updateBinary(binary, outputDir, proxy, ignoreSSL).then(() => { + return Promise.resolve(updateBrowserFile(binary, outputDir)); + })); + } + if (android) { + let binary = binaries[binaries_1.AndroidSDK.id]; + let sdk_path = path.resolve(outputDir, binary.executableFilename()); + let oldAVDList; + updateBrowserFile(binary, outputDir); + promises.push(q.nfcall(fs.readFile, path.resolve(sdk_path, 'available_avds.json')) + .then((oldAVDs) => { + oldAVDList = oldAVDs; + }, () => { + oldAVDList = '[]'; + }) + .then(() => { + return updateBinary(binary, outputDir, proxy, ignoreSSL); + }) + .then(() => { + initialize_1.android(path.resolve(outputDir, binary.executableFilename()), android_api_levels, android_architectures, android_platforms, android_accept_licenses, binaries[binaries_1.AndroidSDK.id].versionCustom, JSON.parse(oldAVDList), logger, verbose); + })); + } + if (ios) { + initialize_1.iOS(logger); + } + if (android || ios) { + installAppium(binaries[binaries_1.Appium.id], outputDir); + updateBrowserFile(binaries[binaries_1.Appium.id], outputDir); + } + return Promise.all(promises).then(() => { + writeBrowserFile(outputDir); + }); +} +function updateBinary(binary, outputDir, proxy, ignoreSSL) { + return files_1.FileManager + .downloadFile(binary, outputDir, (binary, outputDir, fileName) => { + unzip(binary, outputDir, fileName); + }) + .then(downloaded => { + if (!downloaded) { + // The file did not have to download, we should unzip it. + logger.info(binary.name + ': file exists ' + path.resolve(outputDir, binary.filename())); + let fileName = binary.filename(); + unzip(binary, outputDir, fileName); + logger.info(binary.name + ': ' + binary.executableFilename() + ' up to date'); + } + }); +} +function unzip(binary, outputDir, fileName) { + // remove the previously saved file and unzip it + let osType = config_1.Config.osType(); + let mv = path.resolve(outputDir, binary.executableFilename()); + try { + fs.unlinkSync(mv); + } + catch (err) { + try { + rimraf.sync(mv); + } + catch (err2) { + } + } + // unzip the file + logger.info(binary.name + ': unzipping ' + fileName); + if (fileName.slice(-4) == '.zip') { + try { + let zip = new AdmZip(path.resolve(outputDir, fileName)); + zip.extractAllTo(outputDir, true); + } + catch (e) { + throw new Error(`Invalid filename: ${path.resolve(outputDir, fileName)}`); + } + } + else { + // We will only ever get .tar files on linux + child_process.spawnSync('tar', ['zxvf', path.resolve(outputDir, fileName), '-C', outputDir]); + } + // rename + if (fileName.indexOf('chromedriver_') != -1) { + fs.renameSync(path.resolve(outputDir, 'chromedriver-mac-x64', binary.zipContentName()), mv) + } else { + fs.renameSync(path.resolve(outputDir, binary.zipContentName()), mv); + } + // set permissions + if (osType !== 'Windows_NT') { + logger.info(binary.name + ': setting permissions to 0755 for ' + mv); + if (binary.id() !== binaries_1.AndroidSDK.id) { + fs.chmodSync(mv, '0755'); + } + else { + fs.chmodSync(path.resolve(mv, 'tools', 'android'), '0755'); + fs.chmodSync(path.resolve(mv, 'tools', 'emulator'), '0755'); + // TODO(sjelin): get 64 bit versions working + } + } +} +function installAppium(binary, outputDir) { + logger.info('appium: installing appium'); + let folder = path.resolve(outputDir, binary.filename()); + try { + rimraf.sync(folder); + } + catch (err) { + } + fs.mkdirSync(folder); + fs.writeFileSync(path.resolve(folder, 'package.json'), JSON.stringify({ scripts: { appium: 'appium' } })); + utils_1.spawn('npm', ['install', 'appium@' + binary.version()], null, { cwd: folder }); +} +function updateBrowserFile(binary, outputDir) { + let currentDownload = path.resolve(outputDir, binary.executableFilename()); + // if browserFile[id] exists, we should update it + if (browserFile[binary.id()]) { + let binaryPath = browserFile[binary.id()]; + if (binaryPath.last === currentDownload) { + return; + } + else { + binaryPath.last = currentDownload; + for (let bin of binaryPath.all) { + if (bin === currentDownload) { + return; + } + } + binaryPath.all.push(currentDownload); + } + } + else { + // The browserFile[id] does not exist / has not been downloaded previously. + // We should create the entry. + let binaryPath = { last: currentDownload, all: [currentDownload] }; + browserFile[binary.id()] = binaryPath; + } +} +function writeBrowserFile(outputDir) { + let filePath = path.resolve(outputDir, 'update-config.json'); + fs.writeFileSync(filePath, JSON.stringify(browserFile)); +} +// for testing +function clearBrowserFile() { + browserFile = {}; +} +exports.clearBrowserFile = clearBrowserFile; +//# sourceMappingURL=update.js.map \ No newline at end of file