git.iko.soy/typeable/elm-ui
on master help sign in
Automated Browser and App Testing
commitdeacf30a2e4de3ae2982e697aa1dbb3446176be0 authorMatthew Griffith <mdg.griffith@gmail.com> dateSun 30 Dec 2018, 08:44 (8 years ago) parent3440537
6 files changed+246−61
.gitignore+6−1 tests/Makefile+13 tests/README.md+31−1 tests/automation/environments.py+91 tests/automation/run.py+105 tests/automation/selenium_test.py−59
.gitignore+6−1
@@ -14,4 +14,9 @@ elm.js
1414
1515examples/temporary/
1616
17−.vscode
17+.vscode
18+
19+
20+sauce.env
21+
22+__pycache__
tests/Makefilenew file+13
@@ -0,0 +1,13 @@
1+compile:
2+ elm make Tests/Run.elm --output=elm.js
3+
4+local_test:
5+ source env/bin/activate
6+ source sauce.env
7+ python3 automation/selenium_test.py --local
8+
9+remote_test:
10+ source env/bin/activate
11+ source sauce.env
12+ python3 automation/run.py
13+
tests/README.md+31−1
@@ -22,4 +22,34 @@ In order to run the test locally, compile
2222
2323`elm make Tests/Run.elm --output elm.js`
2424
25−and then open `gather-styles.html`
25+and then open `gather-styles.html`
26+
27+Alternatively, you can run the tests locally using selenium by running:
28+
29+`python3 automation/run.py --local`
30+
31+from the `tests` directory.
32+
33+
34+# Running on Sauce Labs
35+
36+In order to automate some of this stuff, this test can be run on Sauce Labs.
37+
38+If you have an account, you'll need to create a `elm-ui/sauce.env` file, which has the following fields:
39+
40+```
41+export SAUCE_ACCESS_KEY={your key}
42+export SAUCE_USERNAME={your username}
43+```
44+You can then run.
45+
46+`python3 automation/run.py`
47+
48+**Note**: The compiled `elm-ui` test needs to be made public somewhere in order for this to work. At the moment it's at my github.io account, though something more permanenet might be set up.
49+
50+
51+# Sauce Labs References
52+
53+https://wiki.saucelabs.com/display/DOCS/Platform+Configurator#/
54+https://wiki.saucelabs.com/display/DOCS/Sauce+Labs+Basics
55+https://github.com/saucelabs-sample-test-frameworks/Python-Pytest-Selenium
tests/automation/environments.pynew file+91
@@ -0,0 +1,91 @@
1+
2+
3+import appium
4+import selenium
5+import selenium.webdriver.firefox.options
6+import os
7+
8+browsers = {'Windows 10':
9+ {'internet explorer': ['11.285'], 'MicrosoftEdge': ['18.17763'], 'chrome': ['71.0'], 'firefox': ['64.0']
10+ },
11+ "macOS 10.14":
12+ {'chrome': ['71.0'], 'firefox': ['64.0'], 'safari': ['12.0']}
13+
14+ }
15+
16+
17+def desktop():
18+
19+ caps = []
20+ for platform, brows in browsers.items():
21+ for browser, versions in brows.items():
22+ for vers in versions:
23+ cap = {'platform': platform,
24+ 'browserName': browser, 'version': vers}
25+
26+ caps.append(
27+ {'driver_type': 'desktop',
28+ 'capabilities': cap})
29+
30+ return caps
31+
32+
33+def local():
34+ options = selenium.webdriver.firefox.options.Options()
35+ options.set_headless(True)
36+
37+ driver = selenium.webdriver.Firefox(options=options)
38+ caps = {}
39+ caps['browserName'] = "firefox"
40+ caps['platform'] = "macOS 10.14"
41+ return [{'driver_type': 'local', 'capabilities': caps}]
42+
43+
44+def mobile():
45+
46+ caps = {}
47+ caps['browserName'] = "Safari"
48+ caps['appiumVersion'] = "1.9.1"
49+ caps['deviceName'] = "iPhone XS Simulator"
50+ caps['deviceOrientation'] = "portrait"
51+ caps['platformVersion'] = "12.0"
52+ caps['platformName'] = "iOS"
53+ return [{'capabilities': caps, 'driver_type': 'app'}]
54+
55+
56+def get_credentials():
57+ return {'username': os.environ['SAUCE_USERNAME'], 'access_key': os.environ['SAUCE_ACCESS_KEY']}
58+
59+
60+def start_driver(env, capabilities):
61+ if env == 'app':
62+ return app(capabilities)
63+ elif env == 'desktop':
64+ return remote(capabilities)
65+ else:
66+ options = selenium.webdriver.firefox.options.Options()
67+ options.set_headless(True)
68+
69+ return selenium.webdriver.Firefox(options=options)
70+
71+
72+def remote(desired_cap):
73+ creds = get_credentials()
74+ driver = selenium.webdriver.Remote(
75+ command_executor='http://{username}:{key}@ondemand.saucelabs.com:80/wd/hub'.format(
76+ username=creds['username'],
77+ key=creds['access_key']),
78+ desired_capabilities=desired_cap)
79+
80+ return driver
81+
82+
83+def app(desired_cap):
84+ creds = get_credentials()
85+ driver = appium.webdriver.Remote(
86+ command_executor='http://{username}:{key}@ondemand.saucelabs.com:80/wd/hub'.format(
87+ username=creds['username'],
88+ key=creds['access_key']),
89+ desired_capabilities=desired_cap)
90+
91+ return driver
tests/automation/run.pynew file+105
@@ -0,0 +1,105 @@
1+import os
2+import time
3+import pprint
4+import json
5+import sys
6+
7+import environments
8+
9+
10+def run(env, url):
11+ driver = environments.start_driver(env['driver_type'], env['capabilities'])
12+
13+ test_run = run_test(driver, url)
14+ return {'capabilities': env['capabilities'], 'failures': test_run, 'success': test_run == []}
15+
16+
17+def log_results(all_results):
18+
19+ for group in all_results:
20+ print(group["label"])
21+ all_pass = True
22+ for result in group["results"]:
23+ name = result[0]
24+ val = result[1]
25+
26+ if val is not None:
27+ print(" Failed - " + name)
28+ all_pass = False
29+ # { given : Maybe String
30+ # , description : String
31+ # , reason : Failure.Reason
32+ # }
33+ pprint.pprint(val)
34+
35+ if all_pass:
36+ print(" All passed!")
37+
38+
39+def only_failures(all_results):
40+ failures = []
41+ for group in all_results:
42+
43+ for result in group["results"]:
44+ name = result[0]
45+ val = result[1]
46+
47+ if val is not None:
48+ failures.append(
49+ {'group': group['label'], 'description': name, 'result': val})
50+
51+ return failures
52+
53+
54+def run_test(driver, url):
55+ print("Running test...")
56+ results = None
57+ try:
58+ # print("Opening Browser")
59+ driver.get(url)
60+
61+ # print("Checking Results")
62+ time.sleep(20)
63+ for x in range(60):
64+ feedback = driver.execute_script('return test_results')
65+ if feedback != "waiting..":
66+ results = only_failures(feedback)
67+ # log_results(feedback)
68+ break
69+ time.sleep(1)
70+ except Exception as inst:
71+ print(type(inst))
72+ print(inst.args)
73+ print(inst)
74+ driver.quit()
75+ else:
76+ print("Finished!")
77+ driver.quit()
78+
79+ return results
80+
81+
82+if __name__ == "__main__":
83+
84+ url = "http://mdgriffith.github.io/elm-ui/tests/base/"
85+
86+ results = []
87+ if len(sys.argv) > 1:
88+ if sys.argv[1] == "--local":
89+ envs = environments.local()
90+ else:
91+ raise "Unknown argument, run --local to run locally."
92+ else:
93+ envs = environments.desktop()
94+ envs.extend(environments.mobile())
95+
96+ for env in envs:
97+ pprint.pprint(env['capabilities'])
98+ result = run(env, url)
99+ results.append(result)
100+ print("--")
101+
102+ pprint.pprint(results)
103+
104+ with open("results/test-results.json", 'w') as RESULTS:
105+ RESULTS.write(json.dumps(results, indent=4))
tests/automation/selenium_test.pydeleted−59
@@ -1,59 +0,0 @@
1−from selenium import webdriver
2−from selenium.webdriver.common.keys import Keys
3−from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
4−import os
5−import time
6−
7−
8−def browsers():
9−
10− capabilities = [
11− {'platform': "Mac OS X 10.9",
12− 'browserName': "chrome",
13− 'version': "31",
14− }
15− ]
16− return capabilies
17−
18−
19−def run_local():
20− driver = webdriver.Firefox()
21− local_file = "file://" + os.getcwd() + "/gather-styles.html"
22− run_test(driver, local_file)
23−
24−
25−def get_credentials():
26− return {'username': os.environ['SAUCE_USERNAME'], 'access_key': os.environ['SAUCE_ACCESS_KEY']}
27−
28−
29−def run_remote(desired_cap):
30− creds = get_credentials()
31− driver = webdriver.Remote(
32− command_executor='http://{username}:{key}@ondemand.saucelabs.com:80/wd/hub'.format(
33− username=creds['username'],
34− key=creds['access_key']),
35− desired_capabilities=desired_cap)
36− run_test(driver)
37−
38−
39−def run_test(driver, url):
40− try:
41− driver.get(local_file)
42− for x in range(5):
43− results = driver.execute_script('return test_results')
44− if results != "waiting..":
45− print(results)
46− break
47− time.sleep(1)
48− except Exception as inst:
49− print(type(inst))
50− print(inst.args)
51− print(inst)
52− driver.quit()
53− else:
54− print("quitting browser")
55− driver.quit()
56−
57−
58−if __name__ == "__main__":
59− run_local()