Projet

Général

Profil

Bug #22333 » mjs-frx-headless.py

Josué Kouka, 09 mars 2018 16:52

 
1
#!/usr/bin/env python
2

    
3
import json
4
import sys
5
# import time
6

    
7
from selenium.common import exceptions
8
from selenium.webdriver import Firefox, FirefoxProfile
9
from selenium.webdriver.common.by import By
10
from selenium.webdriver.firefox.options import Options
11
from selenium.webdriver.support import expected_conditions as EC
12
from selenium.webdriver.support.ui import WebDriverWait
13

    
14
firefox_binary_path = '/opt/firefox/firefox'
15
gecko_binary_path = '/opt/firefox/geckodriver'  # http://bit.ly/2iGGDeR
16

    
17

    
18
def get_driver():
19
    options = Options()
20
    # options.set_headless()
21
    profile = FirefoxProfile()
22
    profile.accept_untrusted_certs = True
23
    driver = Firefox(executable_path=gecko_binary_path, firefox_binary=firefox_binary_path,
24
                     firefox_options=options, firefox_profile=profile)
25
    return driver
26

    
27

    
28
class HeadlessBrowser(object):
29

    
30
    def __init__(self, url):
31
        self.url = url
32

    
33
    def __enter__(self):
34
        self.driver = get_driver()
35
        self.driver.get(self.url)
36
        return self.driver
37

    
38
    def __exit__(self, *args):
39
        self.driver.close()
40

    
41

    
42
class App(object):
43

    
44
    def __init__(self, data):
45
        self.data = data
46

    
47
    def check_authentication(self, browser):
48
        raise NotImplementedError
49

    
50
    def before_authentication(self, browser):
51
        return browser
52

    
53
    def authenticate(self):
54
        status = {}
55
        with HeadlessBrowser(self.data['address']) as browser:
56
            # wait couple seconds before processing
57
            try:
58
                WebDriverWait(browser, 1).until(
59
                    EC.presence_of_element_located((By.ID, self.data['locators'].keys()[0].strip('#'))))
60
            except exceptions.TimeoutException:
61
                return {'result': 'timeout', 'reason': 'element no found'}
62
            # run prior attempting an authentication
63
            self.before_authentication(browser)
64
            for key, value in self.data['locators'].iteritems():
65
                element = browser.find_element_by_css_selector(key)
66
                element.send_keys(value)
67
            element.submit()
68
            # check authentication
69
            auth_checked = self.check_authentication(browser)
70
            status['result'] = 'ok' if auth_checked else 'failure'
71
            status['url'] = browser.current_url
72
            status['cookies'] = browser.get_cookies()
73
            # time.sleep(10)
74
        return status
75

    
76

    
77
class Archimed(App):
78

    
79
    def before_authentication(self, browser):
80
        browser.find_element_by_css_selector('#dropMenu1').click()
81
        return browser
82

    
83
    def check_authentication(self, browser):
84
        try:
85
            WebDriverWait(browser, 1).until(
86
                EC.presence_of_element_located((By.CLASS_NAME, 'account_logoff')))
87
        except exceptions.TimeoutException:
88
            return False
89
        return bool(browser.find_elements_by_css_selector('a.account_logoff'))
90

    
91

    
92
class Teamnet(App):
93

    
94
    def check_authentication(self, browser):
95
        try:
96
            WebDriverWait(browser, 1).until(
97
                EC.presence_of_element_located((By.CLASS_NAME, 'infoUtilisateur')))
98
        except exceptions.TimeoutException:
99
            return False
100
        return bool(browser.find_elements_by_css_selector(".infoUtilisateur"))
101

    
102

    
103
class Redmine(App):
104

    
105
    def check_authentication(self, browser):
106
        try:
107
            WebDriverWait(browser, 1).until(
108
                EC.presence_of_element_located((By.ID, 'loggedas')))
109
        except exceptions.TimeoutException:
110
            return False
111
        return bool(browser.find_elements_by_css_selector("#loggedas"))
112

    
113

    
114
if __name__ == "__main__":
115
    """{
116
        'address': 'https://dev.entrouvert.org/login',
117
        'locators': {
118
            '#username': 'whatever',
119
            '#password': 'whatever'
120
        }
121
    }
122
    """
123
    if len(sys.argv) < 2:
124
        print('python headless.py whatever.json')
125
    filename = sys.argv.pop()
126
    data = json.load(open(filename))
127
    if 'entrouvert' in data['address']:
128
        app = Redmine(data)
129
    elif 'montpellier' in data['address']:
130
        app = Archimed(data)
131
    else:
132
        app = Teamnet(data)
133
    print(app.authenticate())