Skip to content

Commit

Permalink
fix: Use chromedriver v2.36 as minimal version for appium:chromedrive…
Browse files Browse the repository at this point in the history
…rExecutableDir usage (#56)

* fix: Use chromedriver v2.36 as minimal version for appium:chromedriverExecutableDir usage

* docs: update readme
  • Loading branch information
KazuCocoa committed May 10, 2024
1 parent 3123820 commit 33b72aa
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 3 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ package in your `package.json`)
|`appium:app`|[Optional] An absolute path to your `.ipk` app file, if you want Appium to install the app.|
|`appium:debuggerPort`|[Optional; default `9998`] The port on the device exposed for remote Chromium debugging.|
|`appium:chromedriverExecutable`(*)|[Optional] Most LG TVs run a very old version of Chrome. Because this driver uses Chromedriver under the hood, you'll need to have a very old version of Chromedriver handy that works with the version of Chrome backing the apps on your TV. In our testing, we've found Chromedriver 2.36 to work with most TVs. You need to tell the driver where you've installed this version of Chromedriver using the `appium:chromedriverExecutable` capability, passing in an absolute path to the Chromedriver binary.|
| `appium:chromedriverExecutableDir`(*) | [Optional] Full path to the folder where chromedriver executables are located. This folder is used then to store the downloaded chromedriver executables if automatic download is enabled with `chromedriver_autodownload` security flag. Please read [Automatic Discovery of Compatible Chromedriver in appium-uiautomator2-driver](https://github.com/appium/appium-uiautomator2-driver?tab=readme-ov-file#automatic-discovery-of-compatible-chromedriver) for more details. |
| `appium:chromedriverExecutableDir`(*) | [Optional] Full path to the folder where chromedriver executables are located. This folder is used then to store the downloaded chromedriver executables if automatic download is enabled with `chromedriver_autodownload` security flag. Please read [Automatic Discovery of Compatible Chromedriver in appium-uiautomator2-driver](https://github.com/appium/appium-uiautomator2-driver?tab=readme-ov-file#automatic-discovery-of-compatible-chromedriver) for more details. If the chrome version on the TV is lower than v63 major version, the using chrome version will be `Chrome/63.0.3239.0` forcefully to use chromedriver 2.36 for the session. Lower chromedriver could raise `cannot find Chrome binary` error, which prevent starting chromedriver session. |
|`appium:websocketPort`|[Optional; default `3000`] The websocket port on the device exposed for remote control|
|`appium:websocketPortSecure`|[Optional; default `3001`] The secure websocket port on the device exposed for remote control|
|`appium:useSecureWebsocket`|[Optional; default `false`] Flag that enables use of `websocketPortSecure` port, also starts WebSocket over https instead. **DISCLAIMER** Enabling this flag, it is required to set environment variable `export NODE_TLS_REJECT_UNAUTHORIZED=0`, which can be a potential security risk. A new session request might get `unable to get local issuer certificate` error message.|
Expand Down
44 changes: 42 additions & 2 deletions lib/driver.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,19 @@ const CHROMEDRIVER_AUTODOWNLOAD_FEATURE = 'chromedriver_autodownload';
*/
const REGEXP_CHROME_VERSION_IN_UA = new RegExp('Chrome\\/(\\S+)');

/**
* To get chrome version from the browser info.
*/
const VERSION_PATTERN = /([\d.]+)/;

/**
* Minimal chrome browser for autodownload.
* Chromedriver for older than this chrome version could have an issue
* to raise no chrome binary error.
*/
const MIN_CHROME_MAJOR_VERSION = 63;
const MIN_CHROME_VERSION = 'Chrome/63.0.3239.0';

// don't proxy any 'appium' routes
/** @type {RouteMatcher[]} */
const NO_PROXY = [
Expand Down Expand Up @@ -206,9 +219,9 @@ export class WebOSDriver extends BaseDriver {
* @property {string} Browser
* @property {string} Protocol-Version
* @property {string} User-Agent
* @property {string} V8-Version
* @property {string} [V8-Version]
* @property {string} WebKit-Version
* @property {string} webSocketDebuggerUrl
* @property {string} [webSocketDebuggerUrl]
*/

/**
Expand Down Expand Up @@ -238,6 +251,32 @@ export class WebOSDriver extends BaseDriver {
return browserVersionInfo;
}

/**
* Set chrome version v63.0.3239.0 as the minimal version
* for autodownload to use proper chromedriver version.
* Older than the chromedriver version could raise no Chrome binary found error,
* which no makes sense for TV automation usage.
*
* @param {BrowserVersionInfo} browserVersionInfo
* @return {BrowserVersionInfo}
*/
fixChromeVersionForAutodownload(browserVersionInfo) {
const chromeVersion = VERSION_PATTERN.exec(browserVersionInfo.Browser ?? '');
if (!chromeVersion) {
return browserVersionInfo;
}

const majorV = chromeVersion[1].split('.')[0];
if (_.toInteger(majorV) < MIN_CHROME_MAJOR_VERSION) {
log.info(`The device chrome version is ${chromeVersion[1]}, ` +
`which could cause an issue for the matched chromedriver version. ` +
`Setting ${MIN_CHROME_VERSION} as browser forcefully`);
browserVersionInfo.Browser = MIN_CHROME_VERSION;
}

return browserVersionInfo;
}

/**
* Returns whether the session can enable autodownloadd feature.
* @returns {boolean}
Expand Down Expand Up @@ -267,6 +306,7 @@ export class WebOSDriver extends BaseDriver {
result = await got.get(`http://${debuggerAddress}/json/version`).json();
log.info(`The response of http://${debuggerAddress}/json/version was ${JSON.stringify(result)}`);
result = this.useUAForBrowserIfNotPresent(result);
result = this.fixChromeVersionForAutodownload(result);

// To respect the executableDir.
executable = undefined;
Expand Down
46 changes: 46 additions & 0 deletions test/unit/driver.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,50 @@ describe('WebOSDriver', function () {
});
});
});

describe('fixChromeVersionForAutodownload', function () {
it('Set minimal chrome version', function () {
const driver = new WebOSDriver();
const browserInfo = {
'Browser': 'Chrome/62.0.4280.88',
'Protocol-Version': '1.3',
'User-Agent': 'Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.4280.88 Safari/537.36',
'WebKit-Version': '537.36 (@cec52f3dd4465dd7389298b97ab723856c556bd)',
};
driver.fixChromeVersionForAutodownload(browserInfo).should.eql(
{
'Browser': 'Chrome/63.0.3239.0',
'Protocol-Version': '1.3',
'User-Agent': 'Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.4280.88 Safari/537.36',
'WebKit-Version': '537.36 (@cec52f3dd4465dd7389298b97ab723856c556bd)',
}
);
});

it('Do nothing if the given browser was empty', function () {
const driver = new WebOSDriver();
const browserInfo = {
'Browser': '',
'Protocol-Version': '1.3',
'User-Agent': 'Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
'V8-Version': '8.7.220.(29*1000 + 2)',
'WebKit-Version': '537.36 (@cec52f3dd4465dd7389298b97ab723856c556bd)',
'webSocketDebuggerUrl': 'ws://192.168.0.1:9998/devtools/browser/a4b3786c-2d2f-4751-9e05-aee2023bc226'
};
driver.fixChromeVersionForAutodownload(browserInfo).should.eql(browserInfo);
});

it('Use the given chrome version', function () {
const driver = new WebOSDriver();
const browserInfo = {
'Browser': 'Chrome/87.0.4280.88',
'Protocol-Version': '1.3',
'User-Agent': 'Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
'V8-Version': '8.7.220.(29*1000 + 2)',
'WebKit-Version': '537.36 (@cec52f3dd4465dd7389298b97ab723856c556bd)',
'webSocketDebuggerUrl': 'ws://192.168.0.1:9998/devtools/browser/a4b3786c-2d2f-4751-9e05-aee2023bc226'
};
driver.fixChromeVersionForAutodownload(browserInfo).should.eql(browserInfo);
});
});
});

0 comments on commit 33b72aa

Please sign in to comment.