Skip to content
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

feat: add support for remote app file #59

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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:deviceName`|[Required] The name of the connected device, as it shows up in `ares-launch --device-list`|
|`appium:deviceHost`|[Required] The IP address of the connected device, as it shows up in `ares-launch --device-list`|
|`appium:appId`|[Required] The app package ID, if you want Appium to use an app already on the TV. Exclusive with `appium:app`|
|`appium:app`|[Optional] An absolute path to your `.ipk` app file, if you want Appium to install the app.|
|`appium:app`|[Optional] A path to your `.ipk` app file if you want Appium to install the app. This can either be an absolute path or a https url to where the file is located on the internet.|
|`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. 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. |
Expand Down
38 changes: 38 additions & 0 deletions lib/cli/ares.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import path from 'path';
import { exec } from 'teen_process';
import { fs, system } from 'appium/support';
import { Env } from '@humanwhocodes/env';
import {createWriteStream, mkdtempSync, rmSync} from 'fs';
import https from 'https';
import {tmpdir} from 'os';

const ARES = 'ares';
const ARES_DEVICE_INFO = 'ares-device-info';
Expand Down Expand Up @@ -148,7 +151,15 @@ export async function closeApp(appId, deviceName) {
*/
export async function installApp(ipkPath, appId, deviceName) {
log.info(`Installing app '${appId}' from ${ipkPath}`);

const isRemoteApp = ipkPath.startsWith('https://');
if (isRemoteApp) {
ipkPath = await downloadRemoteWebosAppToTempFile(ipkPath);
}
await runDeviceCmd(ARES_INSTALL, deviceName, [ipkPath]);
if (isRemoteApp) {
rmSync(ipkPath);
}
}

/**
Expand All @@ -160,3 +171,30 @@ export async function uninstallApp(appId, deviceName) {
log.info(`Uninstalling app '${appId}'`);
await runDeviceCmd(ARES_INSTALL, deviceName, ['-r', appId]);
}

function downloadRemoteWebosAppToTempFile(appUrl) {
const tempDir = mkdtempSync(`${tmpdir()}${path.sep}`);
const filePath = path.join(tempDir, 'app.ipk');
const file = createWriteStream(filePath);

return new Promise((resolve, reject) => {
https.get(appUrl, (response) => {
if (response.statusCode !== 200) {
reject(new Error(`Failed to get '${appUrl}' (${response.statusCode})`));
return;
}

response.pipe(file);
file.on('finish', () => {
file.close(() => resolve(filePath));
});
file.on('error', (err) => {
rmSync(filePath);
reject(err);
});
}).on('error', (err) => {
rmSync(filePath);
reject(err);
});
});
}