325 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			325 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Python
		
	
	
	
| # Copyright 2018 The Chromium OS Authors. All rights reserved.
 | |
| # Use of this source code is governed by a BSD-style license that can be
 | |
| # found in the LICENSE file.
 | |
| 
 | |
| import logging
 | |
| import os
 | |
| import time
 | |
| 
 | |
| from commands import *
 | |
| 
 | |
| from autotest_lib.client.common_lib import error
 | |
| from autotest_lib.client.common_lib.cros import chromedriver
 | |
| from selenium.webdriver.common.keys import Keys
 | |
| from autotest_lib.client.cros.graphics import graphics_utils
 | |
| from selenium.webdriver.common.action_chains import ActionChains
 | |
| from selenium.common.exceptions import WebDriverException
 | |
| 
 | |
| TIMEOUT_TO_COPY = 1800  # in Secs. This timeout is for files beyond 1GB
 | |
| SEARCH_BUTTON_ID = "search-button"
 | |
| SEARCH_BOX_CSS = "div#search-box"
 | |
| PAPER_CONTAINTER = "paper-input-container"
 | |
| DELETE_BUTTON_ID = "delete-button"
 | |
| FILE_LIST_ID = "file-list"
 | |
| LABLE_ENTRY_CSS = "span.label.entry-name"
 | |
| CR_DIALOG_CLASS = "cr-dialog-ok"
 | |
| USER_LOCATION = "/home/chronos/user"
 | |
| # Using graphics_utils to simulate below keys
 | |
| OPEN_FILES_APPLICATION_KEYS = ["KEY_RIGHTSHIFT", "KEY_LEFTALT", "KEY_M"]
 | |
| SWITCH_TO_APP_KEY_COMBINATION = ["KEY_LEFTALT", 'KEY_TAB']
 | |
| SELECT_ALL_KEY_COMBINATION = ["KEY_LEFTCTRL", "KEY_A"]
 | |
| PASTE_KEY_COMBINATION = ["KEY_LEFTCTRL", "KEY_V"]
 | |
| GOOGLE_DRIVE = 'My Drive'
 | |
| 
 | |
| 
 | |
| class files_CopyFileToGoogleDriveUI(graphics_utils.GraphicsTest):
 | |
| 
 | |
|     """Copy a file from Downloads folder to Google drive"""
 | |
| 
 | |
|     version = 1
 | |
|     TIME_DELAY = 5
 | |
|     _WAIT_TO_LOAD = 5
 | |
| 
 | |
|     def initialize(self):
 | |
|         """Autotest initialize function"""
 | |
|         super(files_CopyFileToGoogleDriveUI, self).initialize(
 | |
|                 raise_error_on_hang=True)
 | |
| 
 | |
|     def cleanup(self):
 | |
|         """Autotest cleanup function"""
 | |
|         if self._GSC:
 | |
|             keyvals = self._GSC.get_memory_difference_keyvals()
 | |
|             for key, val in keyvals.iteritems():
 | |
|                 self.output_perf_value(
 | |
|                     description=key,
 | |
|                     value=val,
 | |
|                     units='bytes',
 | |
|                     higher_is_better=False)
 | |
|             self.write_perf_keyval(keyvals)
 | |
|         super(files_CopyFileToGoogleDriveUI, self).cleanup()
 | |
|         # If test fails then script will collect the screen shot to know at
 | |
|         # which instance failure occurred.
 | |
|         if not self.success:
 | |
|             graphics_utils.take_screenshot(os.path.join(self.debugdir),
 | |
|                                            "chrome")
 | |
| 
 | |
|     def switch_to_app(self, driver, title):
 | |
|         """Switching to application using title
 | |
| 
 | |
|         @param driver: chrome driver object
 | |
|         @param title: Title of the application
 | |
|         @return: True if the app is detected otherwise False
 | |
|         """
 | |
|         windows = driver.window_handles
 | |
|         logging.debug("Windows opened: %s", windows)
 | |
|         # Checking current window initially..
 | |
|         logging.debug("Current window is %s", driver.title)
 | |
|         if driver.title.strip().lower() == title.lower():
 | |
|             return True
 | |
|         # Switching to all opened windows to find out the required window
 | |
|         for window in windows:
 | |
|             try:
 | |
|                 logging.debug("Switching to window")
 | |
|                 driver.switch_to_window(window)
 | |
|                 logging.debug("Switched to window: %s", driver.title)
 | |
|                 time.sleep(2)
 | |
|                 if driver.title.strip().lower() == title.lower():
 | |
|                     logging.info("%s application opened!", title)
 | |
|                     return True
 | |
|             except WebDriverException as we:
 | |
|                 logging.debug("Webdriver exception occurred. Exception: %s",
 | |
|                               str(we))
 | |
|             except Exception as e:
 | |
|                 logging.debug("Exception: %s", str(e))
 | |
|         return False
 | |
| 
 | |
|     def open_files_application(self, driver):
 | |
|         """Open and switch to files application using graphics_utils.py
 | |
| 
 | |
|         @param driver: chrome driver object
 | |
|         """
 | |
|         logging.info("Opening files application")
 | |
|         graphics_utils.press_keys(OPEN_FILES_APPLICATION_KEYS)
 | |
|         time.sleep(self._WAIT_TO_LOAD)
 | |
|         try:
 | |
|             self.switch_to_files(driver)
 | |
|         except Exception as e:
 | |
|             logging.error("Exception when switching files application.. %s",
 | |
|                           str(e))
 | |
|             logging.error("Failed to find files application. Trying again.")
 | |
|             graphics_utils.press_keys(OPEN_FILES_APPLICATION_KEYS)
 | |
|             time.sleep(self._WAIT_TO_LOAD)
 | |
|             self.switch_to_files(driver)
 | |
| 
 | |
|     def switch_to_files(self, driver, title="Downloads"):
 | |
|         """Switch to files application
 | |
| 
 | |
|         @param driver: chrome driver object
 | |
|         @param title: Title of the Files application
 | |
|         """
 | |
|         logging.debug("Switching/Focus on the Files app")
 | |
|         if self.switch_to_app(driver, title):
 | |
|             logging.info("Focused on Files application")
 | |
|             graphics_utils.press_keys(SWITCH_TO_APP_KEY_COMBINATION)
 | |
|             time.sleep(1)
 | |
|         else:
 | |
|             raise error.TestFail("Failed to open on Files application")
 | |
| 
 | |
|     def check_folder_opened(self, driver, title):
 | |
|         """Check the selected folder is opened or not
 | |
| 
 | |
|         @param driver: chrome driver object
 | |
|         @param title: Folder name
 | |
|         @return: Returns True if expected folder is opened otherwise False
 | |
|         """
 | |
|         logging.info("Actual files application title is %s", driver.title)
 | |
|         logging.info("Expected files application title is %s", title)
 | |
|         if driver.title == title:
 | |
|             return True
 | |
|         return False
 | |
| 
 | |
|     def open_folder(self, driver, folder):
 | |
|         """Open given folder
 | |
| 
 | |
|         @param driver: chrome driver object
 | |
|         @param folder: Directory name
 | |
|         """
 | |
|         folder_webelements = driver.find_elements_by_css_selector(
 | |
|             LABLE_ENTRY_CSS)
 | |
|         for element in folder_webelements:
 | |
|             try:
 | |
|                 logging.debug("Found folder name: %s", element.text.strip())
 | |
|                 if folder == element.text.strip():
 | |
|                     element.click()
 | |
|                     time.sleep(3)
 | |
|                     if self.check_folder_opened(driver, element.text.strip()):
 | |
|                         logging.info("Folder is opened!")
 | |
|                         return
 | |
|             except Exception as e:
 | |
|                 logging.error("Exception when getting Files application "
 | |
|                               "folders %s", str(e))
 | |
|         raise error.TestError("Folder :%s is not opened or found", folder)
 | |
| 
 | |
|     def list_files(self, driver):
 | |
|         """List files in the folder
 | |
| 
 | |
|         @param driver: chrome driver object
 | |
|         @return: Returns list of files
 | |
|         """
 | |
|         return driver.find_element_by_id(
 | |
|             FILE_LIST_ID).find_elements_by_tag_name('li')
 | |
| 
 | |
|     def search_file(self, driver, file_name):
 | |
|         """Search given file in Files application
 | |
| 
 | |
|         @param driver: chrome driver object
 | |
|         @param file_name: Required file
 | |
|         """
 | |
|         driver.find_element_by_id(SEARCH_BUTTON_ID).click()
 | |
|         search_box_element = driver.find_element_by_css_selector(
 | |
|             SEARCH_BOX_CSS)
 | |
|         search_box_element.find_element_by_css_selector(
 | |
|             PAPER_CONTAINTER).find_element_by_tag_name('input').clear()
 | |
|         search_box_element.find_element_by_css_selector(
 | |
|             PAPER_CONTAINTER).find_element_by_tag_name('input').send_keys(
 | |
|             file_name)
 | |
| 
 | |
|     def copy_file(self, driver, source, destination, file_name, clean=True):
 | |
|         """Copy file from one directory to another
 | |
| 
 | |
|         @param driver: chrome driver object
 | |
|         @param source: Directory name from where to copy
 | |
|         @param destination: Directory name to where to copy
 | |
|         @param file_name: File to copy
 | |
|         @param clean: Cleans destination if True otherwise nothing
 | |
|         """
 | |
|         self.open_folder(driver, source)
 | |
|         self.search_file(driver, file_name)
 | |
|         files = self.list_files(driver)
 | |
|         action_chains = ActionChains(driver)
 | |
| 
 | |
|         for item in files:
 | |
|             logging.info("Selecting file to copy in %s", file_name)
 | |
|             item.click()
 | |
|             file_size = item.text.split()[1].strip()
 | |
|             file_size_units = item.text.split()[2].strip()
 | |
|             logging.debug("Select copy")
 | |
|             action_chains.move_to_element(item) \
 | |
|                 .click(item).key_down(Keys.CONTROL) \
 | |
|                 .send_keys("c") \
 | |
|                 .key_up(Keys.CONTROL) \
 | |
|                 .perform()
 | |
|             self.open_folder(driver, destination)
 | |
|             if clean:
 | |
|                 drive_files = self.list_files(driver)
 | |
|                 if len(drive_files) != 0:
 | |
|                     logging.info("Removing existing files from %s",
 | |
|                                  destination)
 | |
|                     drive_files[0].click()
 | |
|                     logging.debug("Select all files/dirs")
 | |
|                     graphics_utils.press_keys(SELECT_ALL_KEY_COMBINATION)
 | |
|                     time.sleep(0.2)
 | |
|                     driver.find_element_by_id(DELETE_BUTTON_ID).click()
 | |
|                     driver.find_element_by_class_name(CR_DIALOG_CLASS).click()
 | |
|                     time.sleep(self.TIME_DELAY)
 | |
|             logging.debug("Pressing control+v to paste the file in required "
 | |
|                           "location")
 | |
|             graphics_utils.press_keys(PASTE_KEY_COMBINATION)
 | |
|             time.sleep(self.TIME_DELAY)
 | |
|             # Take dummy values initially
 | |
|             required_file_size = "0"
 | |
|             required_file_size_units = "KB"
 | |
|             required_file = None
 | |
|             # wait till the data copied
 | |
|             start_time = time.time()
 | |
|             while required_file_size != file_size and \
 | |
|                 required_file_size_units != file_size_units and \
 | |
|                     (time.time() - start_time <= TIMEOUT_TO_COPY):
 | |
|                 drive_files_during_copy = self.list_files(driver)
 | |
|                 if len(drive_files_during_copy) == 0:
 | |
|                     raise error.TestError("File copy not started!")
 | |
|                 for i_item in drive_files_during_copy:
 | |
|                     if i_item.text.strip().split()[0].strip() == file_name:
 | |
|                         logging.info("File found %s", i_item.text.split()[
 | |
|                             0].strip())
 | |
|                         required_file = file
 | |
|                 if not required_file:
 | |
|                     raise error.TestError("No such file/directory in drive, "
 | |
|                                           "%s", required_file)
 | |
|                 logging.info(required_file.text.split())
 | |
|                 required_file_size = required_file.text.split()[1]
 | |
|                 required_file_size_units = required_file.text.split()[2]
 | |
|                 time.sleep(5)
 | |
|                 logging.debug("%s %s data copied" % (required_file_size,
 | |
|                                                      required_file_size_units))
 | |
|             # Validation starts here
 | |
|             found = False
 | |
|             drive_files_after_copy = self.list_files(driver)
 | |
|             for copied_file in drive_files_after_copy:
 | |
|                 logging.debug("File in destination: %s",
 | |
|                               copied_file.text.strip())
 | |
|                 if copied_file.find_element_by_class_name(
 | |
|                         'entry-name').text.strip() == file_name:
 | |
|                     found = True
 | |
|                     break
 | |
| 
 | |
|             if found:
 | |
|                 logging.info("Copied the file successfully!")
 | |
|             else:
 | |
|                 raise error.TestFail("File not transferred successfully!")
 | |
| 
 | |
|     def catch_info_or_error_messages(self, driver):
 | |
|         """Logic to catch the error
 | |
| 
 | |
|         @param driver: chrome driver object
 | |
|         """
 | |
|         errors = []
 | |
|         try:
 | |
|             driver.find_element_by_css_selector(
 | |
|                 'div.button-frame').find_element_by_class_name('open').click()
 | |
|         except Exception as e:
 | |
|             logging.info("Error in open error messages")
 | |
|             logging.info(str(e))
 | |
|         error_elements = driver.find_elements_by_css_selector(
 | |
|             'div.progress-frame')
 | |
|         if len(error_elements) != 0:
 | |
|             for error_element in error_elements:
 | |
|                 info_text = error_element.find_element_by_tag_name(
 | |
|                     'label').text
 | |
|                 if info_text != "":
 | |
|                     errors.append(info_text)
 | |
|         return errors
 | |
| 
 | |
|     def create_file(self, filename):
 | |
|         """Create a file"""
 | |
|         status, output = getstatusoutput('dd if=/dev/zero of=%s bs=%s '
 | |
|                                          'count=1 iflag=fullblock' %
 | |
|                                          (filename, 1024))
 | |
|         if status:
 | |
|             raise error.TestError("Failed to create file")
 | |
| 
 | |
|     def run_once(self, username=None, password=None, source="Downloads",
 | |
|                  file_name='test.dat'):
 | |
|         """Copy file to Google Drive in Files application
 | |
| 
 | |
|         @param username: Real user(Not default autotest user)
 | |
|         @param password: Password for the user.
 | |
|         @param source: From where to copy file
 | |
|         @param file_name: File name
 | |
|         """
 | |
|         self.success = False  # Used to capture the screenshot if the TC fails
 | |
|         with chromedriver.chromedriver(username=username,
 | |
|                                        password=password,
 | |
|                                        disable_default_apps=False,
 | |
|                                        gaia_login=True) as cr_instance:
 | |
|             driver = cr_instance.driver
 | |
|             self.open_files_application(driver)
 | |
|             self.create_file(os.path.join(os.path.join(USER_LOCATION,
 | |
|                                                        source), file_name))
 | |
|             self.copy_file(driver, source, GOOGLE_DRIVE, file_name)
 | |
|             errors = self.catch_info_or_error_messages(driver)
 | |
|             if len(errors):
 | |
|                 raise error.TestFail("Test failed with the following"
 | |
|                                      " errors. %s", errors)
 | |
|         self.success = True
 |