diff --git a/marionette-screenshots/README b/marionette-screenshots/README new file mode 100644 index 0000000..5a1b8f2 --- /dev/null +++ b/marionette-screenshots/README @@ -0,0 +1 @@ +Screenshot web-pages using Firefox diff --git a/marionette-screenshots/marionette_screenshot.py b/marionette-screenshots/marionette_screenshot.py new file mode 100644 index 0000000..17adbd2 --- /dev/null +++ b/marionette-screenshots/marionette_screenshot.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import io +import os +import subprocess +import tempfile +from contextlib import contextmanager +import shutil + +from PIL import Image +import click +from marionette_driver.marionette import Marionette +from marionette_driver import expected, Wait, By + + +@contextmanager +def tempdir(*args, **kwargs): + path = tempfile.mkdtemp(*args, **kwargs) + try: + yield path + finally: + shutil.rmtree(path) + + +@contextmanager +def process(args): + process = subprocess.Popen(args) + try: + yield process + finally: + process.kill() + + +class Environ(object): + def __getattr__(self, name): + try: + return os.environ[name] + except KeyError: + raise AttributeError(name) + + +class MarionetteWrapper(Marionette): + def full_page_screenshot(self, filename): + img = Image.open(io.BytesIO(self.screenshot(element=None, format='binary', full=True))) + img.save(filename) + + @property + def wait_until_expected(self): + return WaitUntil(self) + + @property + def env(self): + return Environ() + + +class WaitUntilExpected: + def __init__(self, client, name): + self.client = client + self.name = name + + def by_name(self, name): + return self(By.NAME, name) + + def by_css_selector(self, selector): + return self(By.CSS_SELECTOR, selector) + + def __call__(self, *args, **kwargs): + return Wait(self.client).until(getattr(expected, self.name)(*args, **kwargs)) + + +class WaitUntil: + def __init__(self, client): + self.client = client + + def __getattr__(self, name): + return WaitUntilExpected(self.client, name) + + +@click.command() +@click.argument('script_py') +def screenshot(script_py): + global client + + with tempdir() as profile_path: + with process(['firefox', '--marionette', '--no-remote', '--new-instance', '--profile', profile_path, '--headless']): + client = MarionetteWrapper('localhost', '2828') + client.start_session() + with open(script_py) as fd: + exec(fd.read(), {}) + client.cleanup() + + +if __name__ == '__main__': + screenshot() diff --git a/marionette-screenshots/script.py b/marionette-screenshots/script.py new file mode 100644 index 0000000..0c52527 --- /dev/null +++ b/marionette-screenshots/script.py @@ -0,0 +1,14 @@ +from marionette_screenshot import client + +client.navigate('https://portail-citoyen-publik.entrouvert.com') +connexion = client.find_element('partial link text', 'Connexion') +connexion.click() +client.wait_until_expected.element_present.by_name('username') +username = client.find_element('name', 'username') +username.send_keys(client.env.LOGIN) +password = client.find_element('name', 'password') +password.send_keys(client.env.PASSWORD) +button = client.find_element('name', 'login-password-submit') +button.click() +client.wait_until_expected.element_not_present.by_css_selector('.loading') +client.full_page_screenshot('portail-citoyen.png') diff --git a/marionette-screenshots/setup.py b/marionette-screenshots/setup.py new file mode 100755 index 0000000..0d2b579 --- /dev/null +++ b/marionette-screenshots/setup.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python + +from setuptools import setup, find_packages + +with open('README') as f: + readme = f.read() + +setup( + name='marionette-screenshot', + version='0.6.0', + description='Git porcelain to interface with Redmine', + long_description=readme, + py_modules=['marionette_screenshot'], + author="Benjamin Dauvergne", + author_email="bdauvergne@entrouvert.com", + install_requires=[ + 'Click', + 'marionette-driver', + 'pillow', + ], + entry_points={ + 'console_scripts': ['marionette-screenshots=marionette_screenshot:screenshot'], + } +) diff --git a/marionette-screenshots/tox.ini b/marionette-screenshots/tox.ini new file mode 100644 index 0000000..06f5d39 --- /dev/null +++ b/marionette-screenshots/tox.ini @@ -0,0 +1,8 @@ +[tox] +envlist = py3 + +[testenv] +passenv = +setenv = +commands = + marionette-screenshots script.py