Compare commits

...
21 Commits
Author SHA1 Message Date
budi 6302de6bc4 Updated base image 2025-09-03 13:55:28 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
1e1c60fc89 [pip] Bump coverage from 7.10.5 to 7.10.6 (#532)
Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.10.5 to 7.10.6.
- [Release notes](https://github.com/nedbat/coveragepy/releases)
- [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst)
- [Commits](https://github.com/nedbat/coveragepy/compare/7.10.5...7.10.6)

---
updated-dependencies:
- dependency-name: coverage
  dependency-version: 7.10.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-01 11:47:29 +02:00
Juan Pedro Bretti MandaranoandGitHub 2a12e66077 Fix typo in WSL configuration file name (#531)
There is no documentation that file `/etc/wsl2.conf` does exist.
According to Microsoft documentation, it is called `/etc/wsl.conf`. 

See https://learn.microsoft.com/en-us/windows/wsl/wsl-config for reference.
2025-09-01 11:47:09 +02:00
budi f2a418d712 Updated base image 2025-08-28 11:25:11 +02:00
budi 44dcc5b166 Updated novnc and websockify 2025-08-25 15:42:55 +02:00
budi 2e88c06124 Updated base image 2025-08-25 15:42:20 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
6b34c74a25 [pip] Bump coverage from 7.10.4 to 7.10.5 (#530)
Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.10.4 to 7.10.5.
- [Release notes](https://github.com/nedbat/coveragepy/releases)
- [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst)
- [Commits](https://github.com/nedbat/coveragepy/compare/7.10.4...7.10.5)

---
updated-dependencies:
- dependency-name: coverage
  dependency-version: 7.10.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-25 02:06:36 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
1fc2c74d8c [pip] Bump requests from 2.32.3 to 2.32.5 (#528)
Bumps [requests](https://github.com/psf/requests) from 2.32.3 to 2.32.5.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.32.3...v2.32.5)

---
updated-dependencies:
- dependency-name: requests
  dependency-version: 2.32.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-20 08:21:10 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
ffbafe87e8 [github-action] Bump actions/checkout from 4 to 5 (#523)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-19 10:53:54 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
62fa6a05c8 [pip] Bump coverage from 7.10.3 to 7.10.4 (#527)
Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.10.3 to 7.10.4.
- [Release notes](https://github.com/nedbat/coveragepy/releases)
- [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst)
- [Commits](https://github.com/nedbat/coveragepy/compare/7.10.3...7.10.4)

---
updated-dependencies:
- dependency-name: coverage
  dependency-version: 7.10.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-19 10:42:11 +02:00
lilinorandGitHub 77542f5b45 Start and stop SaaS devices in parallel (#524) 2025-08-19 09:57:05 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
39df955c26 [pip] Bump coverage from 7.10.2 to 7.10.3 (#522)
Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.10.2 to 7.10.3.
- [Release notes](https://github.com/nedbat/coveragepy/releases)
- [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst)
- [Commits](https://github.com/nedbat/coveragepy/compare/7.10.2...7.10.3)

---
updated-dependencies:
- dependency-name: coverage
  dependency-version: 7.10.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-13 06:13:47 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
8da596a8f1 [pip] Bump coverage from 7.10.1 to 7.10.2 (#521)
Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.10.1 to 7.10.2.
- [Release notes](https://github.com/nedbat/coveragepy/releases)
- [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst)
- [Commits](https://github.com/nedbat/coveragepy/compare/7.10.1...7.10.2)

---
updated-dependencies:
- dependency-name: coverage
  dependency-version: 7.10.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-10 10:20:17 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
7f55b248fd [pip] Bump coverage from 7.10.0 to 7.10.1 (#520)
Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.10.0 to 7.10.1.
- [Release notes](https://github.com/nedbat/coveragepy/releases)
- [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst)
- [Commits](https://github.com/nedbat/coveragepy/compare/7.10.0...7.10.1)

---
updated-dependencies:
- dependency-name: coverage
  dependency-version: 7.10.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-01 00:46:37 +02:00
budi c434ae7770 Updated base image 2025-07-31 19:04:33 +02:00
budi ff9f9268e3 Updated docu 2025-07-28 12:49:43 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
27e95cd197 [pip] Bump coverage from 7.9.2 to 7.10.0 (#519)
Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.9.2 to 7.10.0.
- [Release notes](https://github.com/nedbat/coveragepy/releases)
- [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst)
- [Commits](https://github.com/nedbat/coveragepy/compare/7.9.2...7.10.0)

---
updated-dependencies:
- dependency-name: coverage
  dependency-version: 7.10.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-25 09:39:58 +02:00
budi 1f1224599e Modified github action build 2025-07-04 10:09:16 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
846cd2ed09 [pip] Bump coverage from 7.8.1 to 7.9.2 (#516)
Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.8.1 to 7.9.2.
- [Release notes](https://github.com/nedbat/coveragepy/releases)
- [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst)
- [Commits](https://github.com/nedbat/coveragepy/compare/7.8.1...7.9.2)

---
updated-dependencies:
- dependency-name: coverage
  dependency-version: 7.9.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-04 08:54:21 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
b5fbe9777e [pip] Bump pytest-xdist from 3.7.0 to 3.8.0 (#515)
Bumps [pytest-xdist](https://github.com/pytest-dev/pytest-xdist) from 3.7.0 to 3.8.0.
- [Release notes](https://github.com/pytest-dev/pytest-xdist/releases)
- [Changelog](https://github.com/pytest-dev/pytest-xdist/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-xdist/compare/v3.7.0...v3.8.0)

---
updated-dependencies:
- dependency-name: pytest-xdist
  dependency-version: 3.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-02 08:27:44 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
21ffb20ca6 [pip] Bump setuptools from 80.8.0 to 80.9.0 (#513)
Bumps [setuptools](https://github.com/pypa/setuptools) from 80.8.0 to 80.9.0.
- [Release notes](https://github.com/pypa/setuptools/releases)
- [Changelog](https://github.com/pypa/setuptools/blob/main/NEWS.rst)
- [Commits](https://github.com/pypa/setuptools/compare/v80.8.0...v80.9.0)

---
updated-dependencies:
- dependency-name: setuptools
  dependency-version: 80.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-30 17:00:40 +02:00
9 changed files with 138 additions and 45 deletions
+4 -4
View File
@@ -13,7 +13,7 @@ jobs:
python-version: ["3.8"]
steps:
- name: Checkout the repo
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Run unit-test
run: script -e -c "./app.sh test emulator test 11.0 && sudo mv tmp/* ."
@@ -23,7 +23,7 @@ jobs:
needs: run_test
steps:
- name: Checkout the repo
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Get release version
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
@@ -42,7 +42,7 @@ jobs:
android: ["9.0", "10.0", "11.0", "12.0", "13.0", "14.0"]
steps:
- name: Checkout the repo
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
@@ -67,7 +67,7 @@ jobs:
needs: release_base
steps:
- name: Checkout the repo
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
+32
View File
@@ -0,0 +1,32 @@
name: Run Test on Demand
on:
workflow_dispatch:
jobs:
build_and_test:
runs-on: ubuntu-24.04
steps:
- name: Checkout the repo
uses: actions/checkout@v5
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Set up extension
run: |
echo "${{ secrets.extension }}" > extension.sh
chmod 700 extension.sh
shell: bash
- name: Build base image
run: script -e -c "./app.sh build base test"
- name: Build sample image
run: script -e -c "./app.sh build emulator test 11.0"
- name: Run unit-test
run: script -e -c "./app.sh test emulator test 11.0 && sudo mv tmp/* ."
- name: Publish test result
run: bash <(curl -s https://codecov.io/bash)
+2 -4
View File
@@ -4,16 +4,14 @@ on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
build_and_test:
runs-on: ubuntu-24.04
if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.actor == 'budtmo'
steps:
- name: Checkout the repo
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
+2 -2
View File
@@ -96,7 +96,7 @@ Credit goes to [Guillaume - The Parallel Interface blog](https://www.paralint.co
sudo usermod -a -G kvm ${USER}
```
2. Add necessary flags to `/etc/wsl2.conf` to their respective sections.
2. Add necessary flags to `/etc/wsl.conf` to their respective sections.
```
[boot]
command = /bin/bash -c 'chown -v root:kvm /dev/kvm && chmod 660 /dev/kvm'
@@ -163,7 +163,7 @@ The differences between normal version and pro version are:
|user-behavior-analytics|Yes|No|-|
|proxy|No|Yes|Set up company proxy on Android emulator on fly|
|language|No|Yes|Set up language on Android emulator on fly|
|Newer Android version|No|Yes|Support other newer Android version e.g. Android 15, etc|
|Newer Android version|No|Yes|Support other newer Android version e.g. Android 15, Android 16, etc|
|root-privileged|No|Yes|Able to run command with security privileged|
|headless-mode|No|Yes|Save resources by using headless mode|
|Selenium 4.x integration|No|Yes|Running Appium UI-Tests againt one (Selenium Hub) endpoint for Android- and iOS emulator(s) / device(s)|
+4 -4
View File
@@ -1,9 +1,9 @@
autopep8==2.3.2
click==8.2.1
coverage==7.8.1
coverage==7.10.6
mock==5.2.0
pytest==8.4.1
pytest-cov==6.2.1
pytest-xdist==3.7.0
requests==2.32.3
setuptools==80.8.0
pytest-xdist==3.8.0
requests==2.32.5
setuptools==80.9.0
+89 -28
View File
@@ -1,19 +1,20 @@
import logging
import os
import subprocess
import concurrent.futures
import uuid
from device import Genymotion, DeviceType
from helper import get_env_value_or_raise
from constants import ENV, UTF8
class GenySAAS(Genymotion):
def __init__(self) -> None:
super().__init__()
self.logger = logging.getLogger(self.__class__.__name__)
self.device_type = DeviceType.GENY_SAAS.value
self.created_devices = []
def login(self) -> None:
if os.getenv(ENV.GENY_AUTH_TOKEN):
auth_token = get_env_value_or_raise(ENV.GENY_AUTH_TOKEN)
@@ -23,14 +24,16 @@ class GenySAAS(Genymotion):
password = get_env_value_or_raise(ENV.GENY_SAAS_PASS)
subprocess.check_call(f"gmsaas auth login {user} {password} > /dev/null 2>&1", shell=True)
self.logger.info("successfully logged in!")
def create(self) -> None:
super().create()
# Collect all items first
items = []
for item in self.get_data_from_template(ENV.GENY_SAAS_TEMPLATE_FILE_NAME):
name = ""
template = ""
local_port = ""
# implement like this because local_port param is not a must
for k, v in item.items():
if k.lower() == "name":
@@ -41,40 +44,98 @@ class GenySAAS(Genymotion):
local_port = v
else:
self.logger.warning(f"'{k}' is not supported! Please check the documentation!")
if not name:
import uuid
name = str(uuid.uuid4())
if not template:
self.shutdown_and_logout()
raise RuntimeError(f"'template' is a must parameter and not given!")
else:
self.logger.info(f"name: {name}, template: {template}")
creation_cmd = f"gmsaas instances start {template} {name}"
try:
instance_id = subprocess.check_output(creation_cmd.split()).decode(UTF8).replace("\n", "")
created_device = {f"{name}": {instance_id}}
self.created_devices.append(created_device)
additional_args = ""
if local_port:
additional_args = f"--adb-serial-port {local_port}"
connect_cmd = f"gmsaas instances adbconnect {instance_id} {additional_args}"
subprocess.check_call(f"{connect_cmd}", shell=True)
except Exception as e:
self.shutdown_and_logout()
self.logger.error(e)
exit(1)
items.append({
'name': name,
'template': template,
'local_port': local_port
})
# Start all devices in parallel
with concurrent.futures.ThreadPoolExecutor(max_workers=100) as executor:
try:
# Submit all tasks
future_to_item = {executor.submit(self.create_instance, item): item for item in items}
# Collect results as they complete
for future in concurrent.futures.as_completed(future_to_item):
item = future_to_item[future]
try:
created_device = future.result()
self.created_devices.append(created_device)
self.logger.info(f"Successfully created device: {created_device}")
except Exception as e:
self.logger.error(f"Instance creation failed for {item['name']}: {e}")
self.shutdown_and_logout()
exit(1)
except Exception as e:
self.shutdown_and_logout()
self.logger.error(f"Parallel execution failed: {e}")
exit(1)
def create_instance(self, item_data):
"""Create a single instance and return the result"""
name = item_data['name']
template = item_data['template']
local_port = item_data['local_port']
self.logger.info(f"name: {name}, template: {template}")
creation_cmd = f"gmsaas instances start {template} {name}"
try:
instance_id = subprocess.check_output(creation_cmd.split()).decode(UTF8).replace("\n", "")
# Connect to ADB
additional_args = ""
if local_port:
additional_args = f"--adb-serial-port {local_port}"
connect_cmd = f"gmsaas instances adbconnect {instance_id} {additional_args}"
subprocess.check_call(f"{connect_cmd}", shell=True)
return {f"{name}": instance_id}
except Exception as e:
self.logger.error(f"Failed to create instance {name}: {e}")
raise e
def stop_instance(self, device_info):
"""Stop a single instance"""
for name, instance_id in device_info.items():
try:
subprocess.check_call(f"gmsaas instances stop {instance_id}", shell=True)
self.logger.info(f"device '{name}' is successfully removed!")
return True
except Exception as e:
self.logger.error(f"Failed to stop device '{name}': {e}")
return False
def shutdown_and_logout(self) -> None:
if bool(self.created_devices):
self.logger.info("Created device(s) will be removed!")
for d in self.created_devices:
for n, i in d.items():
subprocess.check_call(f"gmsaas instances stop {i}", shell=True)
self.logger.info(f"device '{n}' is successfully removed!")
# Stop all devices in parallel
with concurrent.futures.ThreadPoolExecutor(max_workers=100) as executor:
# Submit all stop tasks
futures = [executor.submit(self.stop_instance, device) for device in self.created_devices]
# Wait for all to complete
for future in concurrent.futures.as_completed(futures):
try:
future.result()
except Exception as e:
self.logger.error(f"Error during device shutdown: {e}")
# Logout after all devices are stopped
if os.getenv(ENV.GENY_AUTH_TOKEN):
subprocess.check_call("gmsaas auth reset", shell=True)
else:
subprocess.check_call("gmsaas auth logout", shell=True)
self.logger.info("successfully logged out!")
self.logger.info("successfully logged out!")
+1 -1
View File
@@ -1,4 +1,4 @@
FROM appium/appium:v2.19.0-p0
FROM appium/appium:v3.0.1-p1
ARG AUTHORS="Budi Utomo"
LABEL author="${AUTHORS} <budtmo.os@gmail.com>"
+2 -2
View File
@@ -50,8 +50,8 @@ RUN apt-get -qqy update && apt-get -qqy install --no-install-recommends \
#=======
# noVNC
#=======
ENV NOVNC_VERSION="1.4.0" \
WEBSOCKIFY_VERSION="0.11.0" \
ENV NOVNC_VERSION="1.6.0" \
WEBSOCKIFY_VERSION="0.13.0" \
OPT_PATH="/opt"
RUN wget -nv -O noVNC.zip "https://github.com/novnc/noVNC/archive/refs/tags/v${NOVNC_VERSION}.zip" \
&& unzip -x noVNC.zip \
+2
View File
@@ -29,6 +29,7 @@ List of Docker-Images
|13.0|33|Normal|budtmo2/docker-android-pro:emulator_13.0|budtmo2/docker-android-pro:emulator_13.0_<release_version>|
|14.0|34|Normal|budtmo2/docker-android-pro:emulator_14.0|budtmo2/docker-android-pro:emulator_14.0_<release_version>|
|15.0|35|Normal|budtmo2/docker-android-pro:emulator_15.0|budtmo2/docker-android-pro:emulator_15.0_<release_version>|
|16.0|36|Normal|budtmo2/docker-android-pro:emulator_16.0|budtmo2/docker-android-pro:emulator_16.0_<release_version>|
|9.0|28|Headless|budtmo2/docker-android-pro:emulator_headless_9.0|budtmo2/docker-android-pro:emulator_headless_9.0_<release_version>|
|10.0|29|Headless|budtmo2/docker-android-pro:emulator_headless_10.0|budtmo2/docker-android-pro:emulator_headless_10.0_<release_version>|
|11.0|30|Headless|budtmo2/docker-android-pro:emulator_headless_11.0|budtmo2/docker-android-pro:emulator_headless_11.0_<release_version>|
@@ -36,6 +37,7 @@ List of Docker-Images
|13.0|33|Headless|budtmo2/docker-android-pro:emulator_headless_13.0|budtmo2/docker-android-pro:emulator_headless_13.0_<release_version>|
|14.0|34|Headless|budtmo2/docker-android-pro:emulator_headless_14.0|budtmo2/docker-android-pro:emulator_headless_14.0_<release_version>|
|15.0|35|Headless|budtmo2/docker-android-pro:emulator_headless_15.0|budtmo2/docker-android-pro:emulator_headless_15.0_<release_version>|
|16.0|36|Headless|budtmo2/docker-android-pro:emulator_headless_16.0|budtmo2/docker-android-pro:emulator_headless_16.0_<release_version>|
|-|-|Selenium|budtmo2/docker-android-pro:selenium|budtmo2/docker-android-pro:selenium_<release_version>|
***Note: Headless mode does not have any Web-UI***