Source code for inginious.frontend.tests.SeleniumTest

# -*- coding: utf-8 -*-

import os
import threading
import unittest

import web
from inginious.frontend.app import get_app
from nose.plugins.skip import SkipTest
from pymongo import MongoClient
from pyvirtualdisplay import Display
from selenium import webdriver
from selenium.common.exceptions import NoAlertPresentException
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.by import By
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

from inginious.frontend.static_middleware import StaticMiddleware

TEST_ENV = os.environ.get("TEST_ENV", None)
CUSTOM_SELENIUM_EXECUTOR = os.environ.get("CUSTOM_SELENIUM_EXECUTOR", None)
CUSTOM_SELENIUM_BASE_URL = os.environ.get("CUSTOM_SELENIUM_BASE_URL", None)
CUSTOM_FRONTEND_CONF_FILE = os.environ.get("CUSTOM_FRONTEND_CONF_FILE", None)


def _start_frontend(config, host, port, ssh_port):
    semaphore = threading.Semaphore(0)

    def active_callback():
        semaphore.release()

    func, close_app_func = get_app(config)

    inginious_root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..'))
    func = StaticMiddleware(func, [
        ('/static/', os.path.join(inginious_root_path, 'frontend', 'static'))
    ])
    server = web.httpserver.WSGIServer((host, port), func)

    class FrontendThread(threading.Thread):
        def __init__(self):
            super(FrontendThread, self).__init__()
            self.daemon = True

        def run(self):
            try:
                server.start()
            except:
                server.stop()

    thread = FrontendThread()
    thread.start()
    semaphore.acquire()
    return thread, server, close_app_func


def _drop_database(config):
    """ Drop the database before running any test """
    mongo_client = MongoClient(host=config.get('host', 'localhost'))
    mongo_client.drop_database(config.get('database', 'INGIniousFrontendTest'))


[docs]class SeleniumTest(unittest.TestCase):
[docs] def setUp(self): self.frontend_config = { "backend": "remote", "docker_daemons": [{ "remote_host": "192.168.59.103", "remote_docker_port": 2375, "remote_agent_port": 63456 }], "mongo_opt": {"host": "localhost", "database": "INGIniousFrontendTest"}, "tasks_directory": "./inginious/tasks", "containers": { "default": "ingi/inginious-c-default", "sekexe": "ingi/inginious-c-sekexe", }, "superadmins": ["test"], "plugins": [ { "plugin_module": "inginious.frontend.plugins.auth.demo_auth", "users": {"test": "test", "test2": "test", "test3": "test"} } ] } if TEST_ENV == "boot2docker": self.display = None self.driver = webdriver.Remote(command_executor=(CUSTOM_SELENIUM_EXECUTOR or 'http://192.168.59.103:4444/wd/hub'), desired_capabilities=DesiredCapabilities.FIREFOX) self.base_url = CUSTOM_SELENIUM_BASE_URL or "http://192.168.59.3:8081" self.frontend_host = "192.168.59.3" self.frontend_port = 8081 self.frontend_ssh_port = 8082 elif TEST_ENV == "boot2docker-local": self.display = None self.driver = webdriver.Firefox() self.base_url = CUSTOM_SELENIUM_BASE_URL or "http://127.0.0.1:8081" self.frontend_host = "127.0.0.1" self.frontend_port = 8081 self.frontend_ssh_port = 8082 elif False and TEST_ENV == "jenkins": self.display = Display(visible=0, size=(1920, 1080)) self.display.start() self.driver = webdriver.Firefox() self.base_url = CUSTOM_SELENIUM_BASE_URL or "http://localhost:8081" self.frontend_host = "localhost" self.frontend_port = 8081 self.frontend_ssh_port = 8082 self.frontend_config["backend"] = "local" else: raise SkipTest("Env variable TEST_ENV is not properly configured. Please take a look a the documentation to properly configure your " "test environment.") self.driver.maximize_window() self.driver.implicitly_wait(30) self.verificationErrors = [] self.accept_next_alert = True _drop_database(self.frontend_config["mongo_opt"]) self.frontend_thread, self.frontend_server, self.close_app_func = _start_frontend(self.frontend_config, self.frontend_host, self.frontend_port, self.frontend_ssh_port)
[docs] def is_element_present(self, how, what): try: self.driver.find_element(by=how, value=what) except NoSuchElementException as e: return False return True
[docs] def is_alert_present(self): try: self.driver.switch_to_alert() except NoAlertPresentException as e: return False return True
[docs] def close_alert_and_get_its_text(self): try: alert = self.driver.switch_to_alert() alert_text = alert.text if self.accept_next_alert: alert.accept() else: alert.dismiss() return alert_text finally: self.accept_next_alert = True
[docs] def wait_for_presence_css(self, selector): WebDriverWait(self.driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, selector)))
[docs] def tearDown(self): self.driver.quit() if self.display is not None: self.display.stop() self.frontend_server.stop() self.close_app_func() self.frontend_thread.join() _drop_database(self.frontend_config["mongo_opt"]) self.assertEqual([], self.verificationErrors)