def __load_settings(self): self.__config = Configuration(config_file_path=self.__config_file_path, allow_no_value=True) # get [MAIN] options self.__conf_hardware = self.__config.get(Config.MAIN.Hardware) self.__conf_display_width = self.__config.get(Config.MAIN.DisplayWidth) self.__conf_display_height = self.__config.get( Config.MAIN.DisplayHeight) self.__day_brightness = self.__config.get(Config.MAIN.DayBrightness) self.__night_brightness = self.__config.get( Config.MAIN.NightBrightness)
def test_something(self): self.driver = Configuration.create_chrome_driver() self.driver.get(Configuration.ADMIN_URL) time.sleep(3) user_textbox = self.driver.find_element(By.NAME, "log") user_textbox.send_keys(Configuration.USER_NAME) pwd_textbox = self.driver.find_element(By.NAME, "pwd") pwd_textbox.send_keys(Configuration.PASSWORD) pwd_textbox.submit() time.sleep(3) dboard_loaded = self.driver.find_element(By.ID, "wpadminbar").is_displayed() self.assertTrue(dboard_loaded, "Assert that dashboard is loaded") # LogOut logout_link = self.driver.find_element(By.XPATH, "//*[text()='Log Out']") self.driver.get(logout_link.get_attribute("href")) time.sleep(1) logout_msg = self.driver.find_element( By.XPATH, "//*[contains(text(),'logged out')]") self.assertTrue(logout_msg.is_displayed(), "Assert successful logout") self.driver.quit()
def test(self): driver = Configuration.create_chrome_driver() driver.get(Configuration.BLOG_URL) time.sleep(3) expected_title = "CSE Blog" actual_title = driver.title self.assertEqual(actual_title, expected_title)
def setUp(self): chrome_options = Options() chrome_options.headless = True self.driver = Configuration.create_chrome_driver(chrome_options) self.wait = WebDriverWait(self.driver, 60) self.driver.get(Configuration.ADMIN_URL) # Login user_textbox = self.wait.until( expected_conditions.element_to_be_clickable((By.NAME, "log"))) user_textbox.send_keys(Configuration.USER_NAME) self.assertEqual(Configuration.USER_NAME, user_textbox.get_attribute("value"), "Assert the user name text") pwd_textbox = self.wait.until( expected_conditions.element_to_be_clickable((By.NAME, "pwd"))) pwd_textbox.send_keys(Configuration.PASSWORD) self.assertEqual(Configuration.PASSWORD, pwd_textbox.get_attribute("value"), "Assert the password text") submit_button = self.wait.until( expected_conditions.element_to_be_clickable((By.ID, "wp-submit"))) submit_button.click() self.wait.until(expected_conditions.presence_of_element_located, "//*[text()= 'WordPress Events and News']")
def test_(self): self.driver.find_element(By.LINK_TEXT, "Media").click() self.driver.find_element(By.LINK_TEXT, "Add New").click() browse_button = self.driver.find_element(By.ID, "async-upload") file_path = Configuration.get_upload_file_path("file-upload.jpg") browse_button.send_keys(file_path) self.driver.find_element(By.ID, "html-upload").click() self.wait.until( expected_conditions.visibility_of_element_located( (By.CLASS_NAME, "thumbnail")))
def test(self): self.driver = Configuration.create_chrome_driver() self.wait = WebDriverWait(self.driver, 60) self.driver.get(Configuration.ADMIN_URL) # Login user_textbox = self.wait.until( expected_conditions.element_to_be_clickable((By.NAME, "log"))) user_textbox.send_keys(Configuration.USER_NAME) self.assertEqual(Configuration.USER_NAME, user_textbox.get_attribute("value"), "Assert the user name text") pwd_textbox = self.wait.until( expected_conditions.element_to_be_clickable((By.NAME, "pwd"))) pwd_textbox.send_keys(Configuration.PASSWORD) self.assertEqual(Configuration.PASSWORD, pwd_textbox.get_attribute("value"), "Assert the password text") submit_button = self.wait.until( expected_conditions.element_to_be_clickable((By.ID, "wp-submit"))) submit_button.click() self.wait.until(expected_conditions.presence_of_element_located, "//*[text()= 'WordPress Events and News']") # Logout logout_link = self.driver.find_element(By.XPATH, "//*[text()='Log Out']") self.driver.get(logout_link.get_attribute("href")) self.wait.until( expected_conditions.presence_of_element_located( (By.XPATH, "//*[contains(text(), 'logged out')]"))) self.driver.quit()
def setUpClass(self): CSETest.driver = Configuration.create_chrome_driver()
import time from common.config import Configuration driver = Configuration.create_chrome_driver() driver.get(Configuration.BLOG_URL) time.sleep(3) expected_title = "dummy" actual_title = driver.title if expected_title != actual_title: raise Exception( "Failure: Title does not match. Expected: <{}> Actual: <{}> ". format(expected_title, actual_title)) driver.quit()
def setUp(self): self.driver = Configuration.create_chrome_driver() self.driver.get(Configuration.ADMIN_URL) time.sleep(3)
def test_(self): target_path = Configuration.get_screenshot_file_path("dashboard") self.driver.save_screenshot(target_path)
def setUp(self): self.driver = Configuration.create_chrome_driver()
class Main(MainInterface): def __init__(self, config_file_path=None): # catch SIGINT, SIGQUIT and SIGTERM self.__quit_signal = threading.Event() signal.signal(signal.SIGINT, self.__quit) signal.signal(signal.SIGQUIT, self.__quit) signal.signal(signal.SIGTERM, self.__quit) # catch SIGHUP and reload configuration signal.signal(signal.SIGHUP, self.__reload) # load config if config_file_path is None: self.__config_file_path = DEFAULT_CONFIG_FILE else: self.__config_file_path = config_file_path self.__load_settings() # this is the queue that holds the frames to display self.__frame_queue = queue.Queue(maxsize=1) # animation controller # gets initialized in mainloop method self.__animation_controller = AnimationController( self.config, self.frame_queue) # the animation scheduler self.__animation_scheduler = self.__create_scheduler() self.__schedule_lock = Lock() # the nighttime scheduler self.__location = lookup(tzlocal.get_localzone_name().split("/")[1], database()) self.__nighttime_scheduler = BackgroundScheduler() self.__sunrise_job = self.__nighttime_scheduler.add_job( func=self.apply_brightness) self.__sunset_job = self.__nighttime_scheduler.add_job( func=self.apply_brightness) self.__nighttime_scheduler.add_job(func=self.__calculate_nighttimes, trigger=CronTrigger(hour="0,12", minute=0, second=0)) self.__calculate_nighttimes() self.apply_brightness() self.__nighttime_scheduler.start() # create the display object self.__initialize_display() # server interfaces self.__http_server = None self.__rest_server = None self.__tpm2_net_server = None # this signal is set by the reload method self.__reload_signal = EventWithUnsetSignal() def __load_settings(self): self.__config = Configuration(config_file_path=self.__config_file_path, allow_no_value=True) # get [MAIN] options self.__conf_hardware = self.__config.get(Config.MAIN.Hardware) self.__conf_display_width = self.__config.get(Config.MAIN.DisplayWidth) self.__conf_display_height = self.__config.get( Config.MAIN.DisplayHeight) self.__day_brightness = self.__config.get(Config.MAIN.DayBrightness) self.__night_brightness = self.__config.get( Config.MAIN.NightBrightness) def __create_scheduler(self): # start with an empty table self.__schedule_table = [] # create the scheduler scheduler = BackgroundScheduler() # load saved jobs saved_jobs = self.config.get(Config.SCHEDULEDANIMATIONS.ScheduleTable) for job in saved_jobs: entry = ScheduleEntry(**job) # during load of the saved scheduled animations, the ANIMATION_SETTINGS attribute is a dict # it must be converted to the respective class instead animation = self.available_animations[ entry.ANIMATION_SETTINGS["animation_name"]] entry.ANIMATION_SETTINGS = animation.default_animation_settings( **entry.ANIMATION_SETTINGS) # add job to the scheduler scheduler.add_job(func=self.start_animation, trigger=CronTrigger( year=entry.CRON_STRUCTURE.YEAR, month=entry.CRON_STRUCTURE.MONTH, day=entry.CRON_STRUCTURE.DAY, week=entry.CRON_STRUCTURE.WEEK, day_of_week=entry.CRON_STRUCTURE.DAY_OF_WEEK, hour=entry.CRON_STRUCTURE.HOUR, minute=entry.CRON_STRUCTURE.MINUTE, second=entry.CRON_STRUCTURE.SECOND), args=(entry.ANIMATION_SETTINGS, ), kwargs={ "pause_current_animation": True, "block_until_finished": True }, id=entry.JOB_ID) # add it to the internal schedule table # no lock is needed here, because when this method is called only the main thread is running self.__schedule_table.append(entry) return scheduler def __initialize_display(self): # load display plugins display_loader = Loader() display_loader.load_plugins((BASE_DIR / "display").resolve(), plugin_base_class=AbstractDisplay) # create it try: self.__display = display_loader.plugins[ self.__conf_hardware.casefold()](self.__conf_display_width, self.__conf_display_height, self.__display_brightness, config=self.config) self.__clear_display() except KeyError: raise RuntimeError("Display hardware '{}' not known.".format( self.__conf_hardware)) def __calculate_nighttimes(self): s = sun(self.__location.observer, date=datetime.now().date()) if s["sunset"] < datetime.now(tz=tzlocal.get_localzone()): # calling after sunset, so calculate for the next day s = sun(self.__location.observer, date=datetime.now().date() + timedelta(days=1)) self.__sunrise = s["sunrise"] self.__sunset = s["sunset"] self.__sunrise_job.reschedule(trigger=DateTrigger( run_date=self.__sunrise)) self.__sunset_job.reschedule(trigger=DateTrigger( run_date=self.__sunset)) def __start_servers(self): # HTTP server if (self.__config.get(Config.MAIN.HttpServer) and # if the variable is set, that means we're in a reload phase # so the server is already started self.__http_server is None): self.__http_server = HttpServer(self) self.__http_server.start() # REST server if (self.__config.get(Config.MAIN.RestServer) and # if the variable is set, that means we're in a reload phase # so the server is already started self.__rest_server is None): self.__rest_server = RestServer(self) self.__rest_server.start() # TPM2Net server if self.__config.get(Config.MAIN.TPM2NetServer): self.__tpm2_net_server = Tpm2NetServer(self, self.__conf_display_width, self.__conf_display_height) threading.Thread(target=self.__tpm2_net_server.serve_forever, daemon=True).start() def __stop_servers(self): # stop only the servers that are started # except on reload, then do not stop the HTTP and REST server if not self.__reload_signal.is_set(): # HTTP server if self.__http_server: self.__http_server.stop() # REST server if self.__rest_server: self.__rest_server.stop() # TPM2Net server if self.__tpm2_net_server: self.__tpm2_net_server.shutdown() self.__tpm2_net_server.server_close() def __save_schedule_table(self): # this method should be surrounded by a lock # convert the ScheduleEntry instances to dicts (needed for file saving) table = [] for entry in self.__schedule_table: table.append(entry.as_raw_dict()) # save the table in the config self.config.set(Config.SCHEDULEDANIMATIONS.ScheduleTable, table) self.config.save() def __clear_display(self): self.__display.clear_buffer() self.__display.show() def __quit(self, *_): print("Exiting...") self.__quit_signal.set() @property def config(self): return self.__config @property def frame_queue(self): return self.__frame_queue def __reload(self, *_): print("Reloading...") # set the reload and quit signal to exit mainloop self.__reload_signal.set() self.__quit_signal.set() def reload(self): # start reload process self.__reload() # wait until the the __reload_signal is unset self.__reload_signal.wait_unset() def start_animation(self, animation_settings, pause_current_animation=False, block_until_started=False, block_until_finished=False): self.__animation_controller.start_animation( animation_settings=animation_settings, pause_current_animation=pause_current_animation, block_until_started=block_until_started, block_until_finished=block_until_finished) def schedule_animation(self, cron_structure, animation_settings): with self.__schedule_lock: job = self.__animation_scheduler.add_job( func=self.start_animation, trigger=CronTrigger(year=cron_structure.YEAR, month=cron_structure.MONTH, day=cron_structure.DAY, week=cron_structure.WEEK, day_of_week=cron_structure.DAY_OF_WEEK, hour=cron_structure.HOUR, minute=cron_structure.MINUTE, second=cron_structure.SECOND), args=(animation_settings, ), kwargs={ "pause_current_animation": True, "block_until_finished": True }) # create an entry for the schedule table schedule_entry = ScheduleEntry() schedule_entry.JOB_ID = job.id schedule_entry.CRON_STRUCTURE = cron_structure schedule_entry.ANIMATION_SETTINGS = animation_settings self.__schedule_table.append(schedule_entry) # save the new entry in the config self.__save_schedule_table() def stop_animation(self, animation_name=None, blocking=False): self.__animation_controller.stop_animation(animation_name, blocking=blocking) def remove_scheduled_animation(self, schedule_id): with self.__schedule_lock: job_found = False for i in range(0, len(self.__schedule_table)): if self.__schedule_table[i].JOB_ID == schedule_id: job_found = True self.__animation_scheduler.remove_job(schedule_id) # remove the entry from the table del self.__schedule_table[i] break if not job_found: eprint("No scheduled animation with ID '%' found!" % str(schedule_id)) else: # save the modified table self.__save_schedule_table() def modify_scheduled_animation(self, schedule_entry): with self.__schedule_lock: job_found = False for i in range(0, len(self.__schedule_table)): if self.__schedule_table[i].JOB_ID == schedule_entry.JOB_ID: job_found = True # modify the arguments self.__animation_scheduler.modify_job( schedule_entry.JOB_ID, args=(schedule_entry.ANIMATION_SETTINGS, )) # and also reschedule it self.__animation_scheduler.reschedule_job( schedule_entry.JOB_ID, trigger=CronTrigger( year=schedule_entry.CRON_STRUCTURE.YEAR, month=schedule_entry.CRON_STRUCTURE.MONTH, day=schedule_entry.CRON_STRUCTURE.DAY, week=schedule_entry.CRON_STRUCTURE.WEEK, day_of_week=schedule_entry.CRON_STRUCTURE. DAY_OF_WEEK, hour=schedule_entry.CRON_STRUCTURE.HOUR, minute=schedule_entry.CRON_STRUCTURE.MINUTE, second=schedule_entry.CRON_STRUCTURE.SECOND)) # replace the schedule table entry self.__schedule_table[i] = schedule_entry break if not job_found: eprint("No scheduled animation with ID '%' found!" % str(schedule_entry.JOB_ID)) else: # save the modified table self.__save_schedule_table() @property def available_animations(self): return self.__animation_controller.all_animations @property def scheduled_animations(self): return self.__schedule_table def is_animation_running(self, animation_name): return self.__animation_controller.is_animation_running(animation_name) def get_current_animation_name(self): return self.__animation_controller.get_current_animation_name() def get_day_brightness(self): return self.__day_brightness def get_night_brightness(self): return self.__night_brightness def apply_brightness(self, new_day_brightness=None, new_night_brightness=None): if new_day_brightness is not None: self.__day_brightness = new_day_brightness if new_night_brightness is not None: self.__night_brightness = new_night_brightness if (self.__night_brightness == -1 or self.__sunrise <= datetime.now(tz=tzlocal.get_localzone()) <= self.__sunset): self.__display_brightness = self.__day_brightness else: self.__display_brightness = self.__night_brightness self.preview_brightness(self.__display_brightness) def preview_brightness(self, brightness): # apply to the current display if it's already initialized if getattr(self, "_%s__display" % self.__class__.__name__, None) is not None: self.__display.set_brightness(brightness) def mainloop(self): # start the animation controller self.__animation_controller.start() # start the animation scheduler self.__animation_scheduler.start() # start the server interfaces self.__start_servers() first_loop = True # run until '__quit' method was called while not self.__quit_signal.is_set(): # check if there is a frame that needs to be displayed if not self.__frame_queue.empty(): # get frame and display it self.__display.buffer = self.__frame_queue.get() self.__frame_queue.task_done() self.__display.show(gamma=True) # after the first frame is displayed, clear the reload signal if first_loop: self.__reload_signal.clear() first_loop = False else: # to limit CPU usage do not go faster than 60 "fps" on empty queue self.__quit_signal.wait(1 / 60) self.__animation_scheduler.shutdown() self.__animation_controller.stop() self.__clear_display() # stop the server interfaces self.__stop_servers() if self.__reload_signal.is_set(): # reload settings self.__load_settings() # recreate the controller self.__animation_controller = AnimationController( self.config, self.frame_queue) # recreate the scheduler self.__animation_scheduler = self.__create_scheduler() # re-initialize the display self.__initialize_display() # clear quit signal # the reload signal gets cleared after the first frame is displayed again self.__quit_signal.clear() # restart mainloop self.mainloop()
#!/usr/bin/env python3 import argparse from pathlib import Path import sys if __name__ == '__main__': # cli parser parser = argparse.ArgumentParser( description="Create or Update the configuration file.") parser.add_argument("CONFIG_FILE_PATH", type=Path, help="The path of the configuration file.") # get config path args = parser.parse_args(sys.argv[1:]) config_file_path = args.CONFIG_FILE_PATH if config_file_path.exists() and not config_file_path.is_file(): raise ValueError("'%s' is not the path of a file!" % str(config_file_path)) else: # sys.path hack for relative import path = Path(__file__).parent.parent sys.path.append(str(path)) from common.config import Configuration config = Configuration(config_file_path=config_file_path, allow_no_value=True) config.save()