mirror of
https://github.com/budtmo/docker-android.git
synced 2026-07-31 04:07:25 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c844033f6 | ||
|
|
83ba9bb79e | ||
|
|
712d3485ad | ||
|
|
04512a0d16 | ||
|
|
cf0ebd7eb9 | ||
|
|
32cb68f6c9 | ||
|
|
98b0b3a140 | ||
|
|
2c9c421c35 | ||
|
|
afea49a2c8 | ||
|
|
442a10afd2 | ||
|
|
478e0d0e51 | ||
|
|
17d09eb835 | ||
|
|
09c3fbe765 | ||
|
|
b285d8a1da | ||
|
|
46d3a4f8c1 | ||
|
|
033be6d7c4 | ||
|
|
84ed95aac1 | ||
|
|
c298cc7ae1 | ||
|
|
0ab0eaffcf | ||
|
|
0e00cffe4d |
@@ -10,10 +10,6 @@
|
||||
|
||||
Docker-Android is a docker image built to be used for everything related to mobile website testing and Android project.
|
||||
|
||||
<p align="center">
|
||||
<a href="https://youtu.be/pQdpjuYwvp8"><img src="./images/appiumconf2018.png" alt="Appium Conference 2018" width="600"></a>
|
||||
</p>
|
||||
|
||||
Emulator - Samsung Device | Emulator - Nexus Device | Real Device
|
||||
:---------------------------:|:---------------------------:|:---------------------------:
|
||||
![][emulator samsung] |![][emulator nexus] |![][real device]
|
||||
@@ -119,6 +115,33 @@ Docker-Android can be used for building Android project and executing its unit t
|
||||
```bash
|
||||
docker run -it --rm -v $PWD/android-testing/ui/espresso/BasicSample:/root/tmp butomo1989/docker-android-x86-8.1 tmp/gradlew build
|
||||
```
|
||||
|
||||
Control Android connected to host (Emulator or Real Device)
|
||||
-----------------------------------------------------------
|
||||
1. Create a docker container with this command
|
||||
|
||||
```
|
||||
$ docker run --privileged -d -p 6080:6080 -p 5554:5554 -p 5555:5555 -p 4723:4723 --name android-container-appium butomo1989/docker-android-real-device
|
||||
```
|
||||
|
||||
2. Open noVNC [http://localhost:6080](http://localhost:6080)
|
||||
|
||||
3. Open terminal by clicking right on **noVNC** window >> **Terminal emulator**
|
||||
|
||||
4. To connect to host's adb (make sure your host have adb and connected to the device.)
|
||||
|
||||
```
|
||||
$ adb -H host.docker.internal devices
|
||||
```
|
||||
|
||||
To specify port, just add `-P port_number`
|
||||
|
||||
```
|
||||
$ adb -H host.docker.internal -P 5037 devices
|
||||
```
|
||||
|
||||
5. Now your container can access your host devices. But, you need to add `remoteAdbHost` and `adbPort` desired capabilities to make **Appium** can recognise those devices.
|
||||
|
||||
|
||||
Appium and Selenium Grid
|
||||
------------------------
|
||||
@@ -192,9 +215,11 @@ This [document](README_CLOUD.md) contains information about deploying Docker-And
|
||||
Genymotion
|
||||
----------
|
||||
|
||||

|
||||
<p align="center">
|
||||
<img id="geny" src="./images/logo_genymotion_and_dockerandroid.png" />
|
||||
</p>
|
||||
|
||||
For you who do not have ressources to maintain the simulator or to buy machines or need different device profiles, you need to give a try to [Genymotion Cloud](https://www.genymotion.com/cloud/). Docker-Android is integrated with Genymotion on different cloud services, e.g. Genymotion Cloud, AWS, GCP, Alibaba Cloud. Please follow [this document](README_GENYMOTION.md) for more detail.
|
||||
For you who do not have ressources to maintain the simulator or to buy machines or need different device profiles, you need to give a try to [Genymotion Cloud](https://www.genymotion.com/cloud/). Docker-Android is integrated with Genymotion on different cloud services, e.g. Genymotion Cloud, AWS, GCP, Alibaba Cloud. Please follow [this document](README_GENYMOTION.md) or [this blog](https://medium.com/genymobile/run-your-appium-tests-using-docker-android-genymotion-cloud-e4817132ccd8) for more detail.
|
||||
|
||||
Troubleshooting
|
||||
---------------
|
||||
|
||||
@@ -3,7 +3,7 @@ Proxy
|
||||
|
||||
You can enable proxy inside container by passing following environment variables:
|
||||
|
||||
- HTTP_PROXY="\<language>docker\_bridge\_ip\_address>"
|
||||
- HTTP_PROXY="\<docker\_bridge\_ip\_address>"
|
||||
- HTTPS_PROXY="\<docker\_bridge\_ip\_address>"
|
||||
- NO_PROXY="localhost"
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
Genymotion Cloud
|
||||
----------------
|
||||
|
||||

|
||||
|
||||
You can easily scale your Appium tests on Genymotion Android virtual devices in the cloud. They are available on SaaS or as virtual images on AWS, GCP or Alibaba Cloud.
|
||||
|
||||
1. On SaaS <br />
|
||||
@@ -11,7 +13,7 @@ You can easily scale your Appium tests on Genymotion Android virtual devices in
|
||||
export PASS="xxx"
|
||||
export LICENSE="xxx"
|
||||
|
||||
docker run -it --rm -p 4723:4723 -v $PWD/genymotion/example/sample_devices:/root/tmp -e TYPE=genycloud -e USER=$USER -e PASS=$PASS -e LICENSE=$LICENSE butomo1989/docker-android-genymotion
|
||||
docker run -it --rm -p 4723:4723 -v $PWD/genymotion/example/sample_devices:/root/tmp -e TYPE=SaaS -e USER=$USER -e PASS=$PASS -e LICENSE=$LICENSE butomo1989/docker-android-genymotion
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
FROM appium/appium:1.9.1-p0
|
||||
FROM appium/appium:1.10.1-p0
|
||||
|
||||
LABEL maintainer "Budi Utomo <budi.ut.1989@gmail.com>"
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
FROM appium/appium:1.9.1-p0
|
||||
FROM appium/appium:1.10.1-p0
|
||||
|
||||
LABEL maintainer "Budi Utomo <budi.ut.1989@gmail.com>"
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
FROM appium/appium:1.9.1-p0
|
||||
FROM appium/appium:1.10.1-p0
|
||||
|
||||
LABEL maintainer "Budi Utomo <budi.ut.1989@gmail.com>"
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ services:
|
||||
- 4444:4444
|
||||
|
||||
# Please stop this container by using docker stop instead of docker-compose stop
|
||||
cloud:
|
||||
saas:
|
||||
image: butomo1989/docker-android-genymotion
|
||||
depends_on:
|
||||
- selenium_hub
|
||||
@@ -20,7 +20,7 @@ services:
|
||||
- $PWD/sample_apk:/root/tmp/sample_apk
|
||||
- $PWD/sample_devices:/root/tmp
|
||||
environment:
|
||||
- TYPE=genycloud
|
||||
- TYPE=SaaS
|
||||
- TEMPLATE=/root/tmp/devices.json
|
||||
- USER=$USER
|
||||
- PASS=$PASS
|
||||
|
||||
@@ -17,48 +17,39 @@
|
||||
"to_port": 22,
|
||||
"protocol": "tcp",
|
||||
"cidr_blocks": "0.0.0.0/0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "ingress",
|
||||
"configurations": [
|
||||
},
|
||||
{
|
||||
"from_port": 80,
|
||||
"to_port": 80,
|
||||
"protocol": "tcp",
|
||||
"cidr_blocks": "0.0.0.0/0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "ingress",
|
||||
"configurations": [
|
||||
},
|
||||
{
|
||||
"from_port": 443,
|
||||
"to_port": 443,
|
||||
"protocol": "tcp",
|
||||
"cidr_blocks": "0.0.0.0/0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "ingress",
|
||||
"configurations": [
|
||||
},
|
||||
{
|
||||
"from_port": 51000,
|
||||
"to_port": 51000,
|
||||
"to_port": 51100,
|
||||
"protocol": "tcp",
|
||||
"cidr_blocks": "0.0.0.0/0"
|
||||
},
|
||||
{
|
||||
"from_port": 51000,
|
||||
"to_port": 51100,
|
||||
"protocol": "udp",
|
||||
"cidr_blocks": "0.0.0.0/0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "ingress",
|
||||
"type": "egress",
|
||||
"configurations": [
|
||||
{
|
||||
"from_port": 51000,
|
||||
"to_port": 51100,
|
||||
"from_port": 0,
|
||||
"to_port": 65535,
|
||||
"protocol": "udp",
|
||||
"cidr_blocks": "0.0.0.0/0"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
# This script is needed because of https://www.ctl.io/developers/blog/post/gracefully-stopping-docker-containers/
|
||||
|
||||
types=(genycloud aws)
|
||||
types=(saas aws)
|
||||
|
||||
if [ -z "$TYPE" ]; then
|
||||
echo "Please specify one of following types: ${types[@]}"
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 115 KiB |
+2
-1
@@ -124,7 +124,8 @@ def appium_run(avd_name: str):
|
||||
grid_connect = convert_str_to_bool(str(os.getenv('CONNECT_TO_GRID', False)))
|
||||
logger.info('Connect to selenium grid? {connect}'.format(connect=grid_connect))
|
||||
if grid_connect:
|
||||
local_ip = os.popen('ifconfig eth0 | grep \'inet addr:\' | cut -d: -f2 | awk \'{ print $1}\'').read().strip()
|
||||
# Ubuntu 16.04 -> local_ip = os.popen('ifconfig eth0 | grep \'inet addr:\' | cut -d: -f2 | awk \'{ print $1}\'').read().strip()
|
||||
local_ip = os.popen('ifconfig eth0 | grep \'inet\' | cut -d: -f2 | awk \'{ print $2}\'').read().strip()
|
||||
try:
|
||||
mobile_web_test = convert_str_to_bool(str(os.getenv('MOBILE_WEB_TEST', False)))
|
||||
appium_host = os.getenv('APPIUM_HOST', local_ip)
|
||||
|
||||
+47
-24
@@ -58,7 +58,7 @@ function prepare_geny_aws() {
|
||||
echo $ami
|
||||
echo $sg
|
||||
|
||||
#TODO: remove this dirty hack (this version will be ignored anyway!)
|
||||
#TODO: remove this dirty hack
|
||||
if [[ $android_version == null ]]; then
|
||||
echo "[HACK] Version cannot be empty! version will be added!"
|
||||
android_version="6.0"
|
||||
@@ -69,25 +69,28 @@ function prepare_geny_aws() {
|
||||
echo "Custom security group is found!"
|
||||
security_group=""
|
||||
|
||||
for i in $(echo "${sg}" | jq -r '.[] | @base64'); do
|
||||
get_value() {
|
||||
echo ${i} | base64 --decode | jq -r ${1}
|
||||
}
|
||||
|
||||
type=$(get_value '.type')
|
||||
configs=$(get_value '.configurations')
|
||||
|
||||
|
||||
for c in $(echo "${configs}" | jq -r '.[] | @base64'); do
|
||||
is_array=$(echo "${sg}" | jq 'if type=="array" then true else false end')
|
||||
if [ $is_array == "true" ]; then
|
||||
echo "New security group with given rules will be created"
|
||||
for i in $(echo "${sg}" | jq -r '.[] | @base64'); do
|
||||
get_value() {
|
||||
echo ${c} | base64 --decode | jq -r ${1}
|
||||
echo ${i} | base64 --decode | jq -r ${1}
|
||||
}
|
||||
|
||||
from_port=$(get_value '.from_port')
|
||||
to_port=$(get_value '.to_port')
|
||||
protocol=$(get_value '.protocol')
|
||||
cidr_blocks=$(get_value '.cidr_blocks')
|
||||
security_group+=$(cat <<_EOF
|
||||
type=$(get_value '.type')
|
||||
configs=$(get_value '.configurations')
|
||||
|
||||
|
||||
for c in $(echo "${configs}" | jq -r '.[] | @base64'); do
|
||||
get_value() {
|
||||
echo ${c} | base64 --decode | jq -r ${1}
|
||||
}
|
||||
|
||||
from_port=$(get_value '.from_port')
|
||||
to_port=$(get_value '.to_port')
|
||||
protocol=$(get_value '.protocol')
|
||||
cidr_blocks=$(get_value '.cidr_blocks')
|
||||
security_group+=$(cat <<_EOF
|
||||
|
||||
$type {
|
||||
from_port = $from_port
|
||||
@@ -96,9 +99,23 @@ function prepare_geny_aws() {
|
||||
cidr_blocks = ["$cidr_blocks"]
|
||||
}
|
||||
_EOF
|
||||
)
|
||||
)
|
||||
done
|
||||
done
|
||||
done
|
||||
else
|
||||
#TODO: remove this dirty hack
|
||||
echo "Given security group will be used!"
|
||||
is_array="false"
|
||||
security_group=$(cat <<_EOF
|
||||
ingress {
|
||||
from_port = 22
|
||||
to_port = 22
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
_EOF
|
||||
)
|
||||
fi
|
||||
else
|
||||
echo "Custom security is not found! It will use default security group!"
|
||||
security_group=$(cat <<_EOF
|
||||
@@ -189,7 +206,7 @@ resource "aws_instance" "geny_aws_$index" {
|
||||
provider = "aws.provider_$index"
|
||||
ami="\${data.aws_ami.geny_aws_$index.id}"
|
||||
instance_type = "\${var.instance_type_$index}"
|
||||
vpc_security_group_ids = ["\${aws_security_group.geny_sg_$index.name}"]
|
||||
vpc_security_group_ids=["\${aws_security_group.geny_sg_$index.name}"]
|
||||
key_name = "\${aws_key_pair.geny_key_$index.key_name}"
|
||||
tags {
|
||||
Name = "DockerAndroid-\${data.aws_ami.geny_aws_$index.id}"
|
||||
@@ -215,11 +232,17 @@ _EOF
|
||||
echo "$aws_tf_content" > /root/aws_tf_$index.tf
|
||||
|
||||
if [[ $ami != null ]]; then
|
||||
echo "Custom AMI is found!"
|
||||
sed -i "s/.*ami=.*/ ami=\"$ami\"/g" /root/aws_tf_$index.tf
|
||||
echo "Using given AMI!"
|
||||
sed -i "s/.*ami=.*/ ami=\"$ami\"/g" /root/aws_tf_$index.tf
|
||||
else
|
||||
echo "Custom AMI is not found. It will use the latest AMI!"
|
||||
fi
|
||||
|
||||
if [[ $sg != null ]] && [[ $is_array == "false" ]]; then
|
||||
echo "Using given security group: $sg"
|
||||
sed -i "s/.*vpc_security_group_ids=.*/ vpc_security_group_ids=[\"$sg\"]/g" /root/aws_tf_$index.tf
|
||||
fi
|
||||
|
||||
echo "---------------------------------------------------------"
|
||||
|
||||
((index++))
|
||||
@@ -238,7 +261,7 @@ _EOF
|
||||
echo "Connect to adb remotely"
|
||||
for ((i=index;i>=1;i--)); do
|
||||
dns=$(./terraform output public_dns_$i)
|
||||
((sleep ${interval_sleep} && adb connect localhost:${port}) > /dev/null & ssh -i ~/.ssh/id_rsa -oStrictHostKeyChecking=no -q -NL ${port}:localhost:5555 shell@${dns}) &
|
||||
((sleep ${interval_sleep} && adb connect localhost:${port}) > /dev/null & ssh -i ~/.ssh/id_rsa -o ServerAliveInterval=60 -o StrictHostKeyChecking=no -q -NL ${port}:localhost:5555 shell@${dns}) &
|
||||
((port--))
|
||||
time_sleep=$((time_sleep+interval_sleep))
|
||||
done
|
||||
@@ -298,7 +321,7 @@ elif [ "$GENYMOTION" = true ]; then
|
||||
echo "${types[@]}"
|
||||
case $TYPE in
|
||||
"${types[0]}" )
|
||||
echo "Using Genymotion-Cloud"
|
||||
echo "Using Genymotion-Cloud (SaaS)"
|
||||
prepare_geny_cloud
|
||||
run_appium
|
||||
;;
|
||||
|
||||
+2
-1
@@ -1,5 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
ip=$(ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}')
|
||||
#Ubuntu 16.04 -> ip=$(ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}')
|
||||
ip=$(ifconfig eth0 | grep 'inet' | cut -d: -f2 | awk '{ print $2}')
|
||||
socat tcp-listen:5554,bind=$ip,fork tcp:127.0.0.1:5554 &
|
||||
socat tcp-listen:5555,bind=$ip,fork tcp:127.0.0.1:5555
|
||||
|
||||
@@ -64,6 +64,19 @@ class TestApp(TestCase):
|
||||
self.assertTrue(mocked_subprocess.called)
|
||||
self.assertTrue(mocked_appium.called)
|
||||
|
||||
@mock.patch('src.app.prepare_avd')
|
||||
@mock.patch('builtins.open')
|
||||
@mock.patch('subprocess.Popen')
|
||||
def test_run_with_appium_and_relaxed_security(self, mocked_avd, mocked_open, mocked_subprocess):
|
||||
with mock.patch('src.app.appium_run') as mocked_appium:
|
||||
os.environ['APPIUM'] = str(True)
|
||||
os.environ['RELAXED_SECURITY'] = str(True)
|
||||
app.run()
|
||||
self.assertTrue(mocked_avd.called)
|
||||
self.assertTrue(mocked_open.called)
|
||||
self.assertTrue(mocked_subprocess.called)
|
||||
self.assertTrue(mocked_appium.called)
|
||||
|
||||
@mock.patch('src.app.prepare_avd')
|
||||
@mock.patch('builtins.open')
|
||||
@mock.patch('subprocess.Popen')
|
||||
|
||||
Reference in New Issue
Block a user