gnome-desktop-testing r7 - in trunk: . bin desktoptesting gedit seahorse



Author: apulido
Date: Thu Mar 19 12:15:07 2009
New Revision: 7
URL: http://svn.gnome.org/viewvc/gnome-desktop-testing?rev=7&view=rev

Log:
New SSH Seahorse test
New framework



Added:
   trunk/seahorse/generate_ssh.py
   trunk/seahorse/generate_ssh.xml
Modified:
   trunk/bin/desktop-testing
   trunk/desktoptesting/check.py
   trunk/desktoptesting/gnome.py
   trunk/desktoptesting/gnome_constants.py
   trunk/gedit/gedit_chains.py
   trunk/gedit/gedit_chains.xml
   trunk/report.xsl
   trunk/seahorse/generate_pgp.py
   trunk/seahorse/generate_pgp.xml

Modified: trunk/bin/desktop-testing
==============================================================================
--- trunk/bin/desktop-testing	(original)
+++ trunk/bin/desktop-testing	Thu Mar 19 12:15:07 2009
@@ -4,12 +4,16 @@
 import re
 import sys
 import logging
+import xml.dom.minidom
+import ldtp
+import ldtputils
+import traceback
 
 from logging import StreamHandler, FileHandler, Formatter
 from optparse import OptionParser
 from stat import ST_MODE, S_IMODE
 from subprocess import Popen, PIPE
-
+from time import time, gmtime, strftime
 
 # Globals
 TESTS_SHARE = "."
@@ -109,7 +113,7 @@
 
     suite = os.path.basename(file)
 
-    pattern = r"[a-z0-9][-_a-z0-9+.]*.xml"
+    pattern = r"[a-z0-9][-_a-z0-9+.]*.xml$"
     if not re.match(pattern, suite, re.I):
         logging.debug("Suite name `%s' does not match pattern: %s",
             file, pattern)
@@ -157,26 +161,22 @@
 
 def run_suite_file(suite_file, log_file):
     conf_file = os.path.join(TESTS_SHARE, "conffile.ini")
-    if not os.path.exists(conf_file):
-        error("Configuration file `%s' does not exist.", conf_file)
-
-    command = "ldtprunner --conf=%s %s > %s" \
-        % (conf_file, suite_file, log_file)
-    safe_run_command(command)
+    runner = TestSuiteRunner(suite_file)
+    results = runner.run()
+    f = open(log_file, 'w')
+    f.write(results)
+    f.close()
 
-def convert_log_file(log_file, html_file, target_directory):
-    xsl_file = os.path.join(TESTS_SHARE, "report.xsl")
-    if not os.path.exists(xsl_file):
-        error("XSL file `%s' does not exist.", xsl_file)
+def convert_log_file(log_file):
 
     if os.path.exists(SCREENSHOTS_SHARE):
-        screenshot_dir = target_directory + "/screenshots"
+        screenshot_dir = os.path.dirname(log_file) + "/screenshots"
 
         if not os.path.exists(screenshot_dir):            
             safe_make_directory(screenshot_dir)
 
         if len(os.listdir(SCREENSHOTS_SHARE)) > 0:
-            command = "cp " + SCREENSHOTS_SHARE + "/* " + screenshot_dir
+            command = "mv " + SCREENSHOTS_SHARE + "/* " + screenshot_dir
             safe_run_command(command)
 
     log_file_tmp = log_file + ".tmp"
@@ -189,11 +189,16 @@
     os.remove(log_file)
     os.rename(log_file_tmp, log_file)
 
+    xsl_file = os.path.join(TESTS_SHARE, "report.xsl")
+    if not os.path.exists(xsl_file):
+        error("XSL file `%s' does not exist.", xsl_file)
+
+    html_file = log_file.replace(".log", ".html")
+
     command = "xsltproc -o %s %s %s" \
         % (html_file, xsl_file, log_file)
     safe_run_command(command)
-
-
+ 
 def process_suite_file(suite_file, target_directory):
     application_name = os.path.basename(os.path.dirname(suite_file))
     application_target = os.path.join(target_directory, application_name)
@@ -204,9 +209,7 @@
         suite_name.replace(".xml", ".log"))
     run_suite_file(suite_file, log_file)
 
-    html_file = log_file.replace(".log", ".html")
-    convert_log_file(log_file, html_file, application_target)
-
+    convert_log_file(log_file)
 
 def main(args=sys.argv):
     usage = "%prog [OPTIONS]"
@@ -285,7 +288,173 @@
     for suite_file in suite_files:
         process_suite_file(suite_file, options.target)
 
+
     return 0
 
+class TestRunner:
+    def __init__(self):
+        self.result = {}
+    def add_results_to_node(self, node):
+        if self.result == {}: return
+        result = node.ownerDocument.createElement("result")
+        for key, val in self.result.items():
+            if not isinstance(val, list):
+                val = [val]
+            for item in val:
+                n = node.ownerDocument.createElement(key)
+                n.appendChild(n.ownerDocument.createTextNode(str(item)))
+                result.appendChild(n)
+                
+        node.appendChild(result)
+
+    def append_result(self, key, value):
+        l = self.result.get(key, [])
+        l.append(value)
+        self.result[key] = l
+
+    def set_result(self, key, value):
+        self.result[key] = value
+
+    def append_screenshot(self):
+        _logFile = "%s/screenshot-%s.png" % (SCREENSHOTS_SHARE,
+                                             strftime ("%m-%d-%Y-%H-%M-%s"))
+        safe_make_directory(SCREENSHOTS_SHARE)
+        ldtputils.imagecapture(outFile = _logFile)
+        self.append_result('screenshot', _logFile)
+
+
+class TestCaseRunner(TestRunner):
+    def __init__(self, obj, xml_node):
+        TestRunner.__init__(self)
+        self.xml_node = xml_node
+        self.args = {}
+        self.name = xml_node.getAttribute('name')
+        self.test_func = getattr(
+            obj, xml_node.getElementsByTagName('method')[0].firstChild.data)
+        args_element = xml_node.getElementsByTagName('args')
+        if args_element:
+            self._get_args(args_element[0])
+
+    def _get_args(self, node):
+        for n in node.childNodes:
+            if n.nodeType != n.ELEMENT_NODE:
+                continue
+            self.args[n.tagName.encode('ascii')] = n.firstChild.data
+
+    def run(self, logger):
+        starttime = time()
+        try:
+            self.test_func(**self.args)
+        except AssertionError, e:
+            # The test failed.
+            self.append_result('message', str(e))
+            self.append_result('stacktrace', traceback.format_exc())
+            self.append_screenshot()
+            self.set_result('pass', 0)
+        except Exception, e:
+            # There was an unrelated error.
+            self.append_result('message', str(e))
+            self.append_result('stacktrace', traceback.format_exc())
+            self.append_screenshot()
+            self.set_result('error', 1)
+        else:
+            self.set_result('pass', 1)
+        finally:
+            self.set_result('time', time() - starttime)
+        
+        self.add_results_to_node(self.xml_node)
+        
+class TestSuiteRunner(TestRunner):
+    def __init__(self, suite_file, loggerclass=None):
+        TestRunner.__init__(self)
+        self.dom = xml.dom.minidom.parse(suite_file)
+        self._strip_whitespace(self.dom.documentElement)
+        clsname, modname = None, None
+        case_runners = []
+        for node in self.dom.documentElement.childNodes:
+            if node.nodeType != node.ELEMENT_NODE:
+                continue
+            if node.tagName == 'class':
+                modname, clsname = node.firstChild.data.rsplit('.', 1)
+            if node.tagName == 'case':
+                logging.debug("Adding case %s to current test suite.", node.getAttribute("name"))
+                case_runners.append(node)
+        if None in (clsname, modname):
+            raise Exception, "Missing a suite class"
+
+        # Suite file and module are suppose to be in the same directory
+        sys.path.insert(1, os.path.dirname(suite_file))
+        logging.debug("Modname: %s", modname)
+        mod = __import__(modname)
+        sys.path.pop(1)
+
+        cls = getattr(mod, clsname)
+        
+        self.testsuite = cls()
+        
+        self.case_runners = \
+            [TestCaseRunner(self.testsuite, c) for c in case_runners]
+    
+    def run(self, loggerclass=None, setup_once=True):
+        try:
+            self._run(loggerclass, setup_once)
+        except Exception, e:
+            # There was an unrelated error.
+            self.append_result('message', str(e))
+            self.append_result('stacktrace', traceback.format_exc())
+            self.set_result('error', 1)
+            try:
+                self.testsuite.teardown()
+            except:
+                pass
+
+        self.add_results_to_node(self.dom.documentElement)
+
+        return self.dom.toprettyxml('  ')
+            
+    def _run(self, loggerclass, setup_once):
+        if loggerclass:
+            logger = loggerclass()
+        else:
+            logger = ldtp
+
+        if setup_once:
+            # Set up the environment.
+            self.testsuite.setup()
+
+        firsttest = True
+        for testcase in self.case_runners:
+            if not setup_once:
+                # Set up the app for each test, if requested.
+                self.testsuite.setup()
+            if not firsttest:
+                # Clean up from previous run.
+                self.testsuite.cleanup()
+            firsttest = False
+            testcase.run(logger)
+            if not setup_once:
+                # Teardown upthe app for each test, if requested.
+                self.testsuite.teardown()
+
+        if setup_once:
+            # Tear down after entire suite.
+            self.testsuite.teardown()
+
+    def _strip_whitespace(self, element):
+        if element is None: 
+            return
+        sibling = element.firstChild
+        while sibling:
+            nextSibling = sibling.nextSibling
+            if sibling.nodeType == sibling.TEXT_NODE:
+                stripped = sibling.data.strip()
+                if stripped == '':
+                    element.removeChild(sibling)
+                else:
+                    sibling.data = stripped
+            else:
+                self._strip_whitespace(sibling)
+            sibling = nextSibling
+
 if __name__ == "__main__":
     sys.exit(main())

Modified: trunk/desktoptesting/check.py
==============================================================================
--- trunk/desktoptesting/check.py	(original)
+++ trunk/desktoptesting/check.py	Thu Mar 19 12:15:07 2009
@@ -6,6 +6,8 @@
 import filecmp
 import os
 import sys
+import shutil
+from ldtputils import imagecompare
 
 FAIL = "fail"
 PASS = "pass"
@@ -34,10 +36,6 @@
 
         Check.__init__(self)
 
-        if not (os.path.exists(oracle) and os.path.exists(test)):
-            print "Both oracle and test file must exist"
-            sys.exit(0)
-
         self.oracle = oracle
         self.test   = test
 
@@ -52,5 +50,13 @@
         else:
             return FAIL
 
+class ScreenshotCompare(FileComparison):
+    def perform_test(self, max_diff=0.0):
+        res = imagecompare(self.oracle, self.test)
+        if res > max_diff:
+            return FAIL
+        else:
+            return PASS
 
-
+    def calibrate(self):
+        shutil.copy(self.test, self.oracle)

Modified: trunk/desktoptesting/gnome.py
==============================================================================
--- trunk/desktoptesting/gnome.py	(original)
+++ trunk/desktoptesting/gnome.py	Thu Mar 19 12:15:07 2009
@@ -7,74 +7,93 @@
 import ldtp 
 import gnome_constants
 
-def open_and_check_app(app_name, window_title_txt):
-    """
-    Given an application, it tries to open it.
-     
-    @type app_name: string
-    @param app_name: The command to start the application.
-    
-    @type window_title_txt: string 
-    @param window_title_txt: The name of the window to recognize once opened.
-        
-        The naming convention is the following:
-        
-        E{-} Prepend 'frm' if the window is a form, or 'dlg' if the window is a dialog.
-        
-        E{-} Append the window name with no spaces.
-              
-        Example: For the window Disk Usage Analyzer, the window name would be frmDiskUsageAnalyzer.
-    
-    """
-    
-    ldtp.launchapp(app_name)
-
-    ldtp.wait(2)
-    response = ldtp.waittillguiexist(window_title_txt, '', 20)
-    
-    if response == 0:
-        raise ldtp.LdtpExecutionError, "The " + window_title_txt + " window was not found."    
-
 class Application:
     """
     Supperclass for the rest of the applications
     """
-    def __init__(self, name = ""):
+    def __init__(self, name = '', close_type='menu', close_name='mnuQuit'):
+        """
+        @type close_type: string
+        @param close_type: The type of close widget of the application. Types: menu, button.
+        @type close_name: string
+        @param close_name: The name of the exit widget of the application. If not mentioned the default will be used ("Quit").
+        """
         self.name = name
+        self.close_type = close_type
+        self.close_name = close_name
       
+    def setup(self):
+        pass
+
+    def teardown(self):
+        pass
+
+    def cleanup(self):
+        self.set_name('')
+        self.set_close_type('menu')
+        self.set_close_name('mnuQuit')
+
+    def recover(self):
+        self.teardown()
+        sleep(1)
+        self.setup()
+
+    def set_name(self, name):
+        if name is not None:
+            self.name = name
+
+    def set_close_type(self, close_type):
+        if close_type is not None:
+            self.close_type = close_type
+
+    def set_close_name(self, close_name):
+        if close_name is not None:
+            self.close_name = close_name
+
     def remap(self):
         """
         It reloads the application map for the given ooldtp.context.
         """
         ldtp.remap(self.name)
 
-    def exit(self, close_type='menu', close_name='mnuQuit'):
+    def open_and_check_app(self, app_name):
         """
-        Given an application, it tries to quit it.
+        Given an application, it tries to open it.
          
-        @type close_type: string
-        @param close_type: The type of close widget of the application. Types: menu, button.
-        @type close_name: string
-        @param close_name: The name of the exit widget of the application. If not mentioned the default will be used ("Quit").
+        @type app_name: string
+        @param app_name: The command to start the application.
+        """
+        
+        ldtp.launchapp(app_name)
+
+        ldtp.wait(2)
+        response = ldtp.waittillguiexist(self.name, '', 20)
+        
+        if response == 0:
+            raise ldtp.LdtpExecutionError, "The " + self.name + " window was not found."    
+
+    def exit(self):
+        """
+        Given an application, it tries to quit it. 
         """
         try:
             app = ooldtp.context(self.name)
             try:
-                close_widget = app.getchild(close_name)
+                close_widget = app.getchild(self.close_name)
             except ldtp.LdtpExecutionError:
-                raise ldtp.LdtpExecutionError, "The " + close_name + " widget was not found."
+                raise ldtp.LdtpExecutionError, "The " + self.close_name + " widget was not found."
 
-            if close_type == 'menu':
+            if self.close_type == 'menu':
                 close_widget.selectmenuitem()
-            elif close_type == 'button':
+            elif self.close_type == 'button':
                 close_widget.click()
             else:
                 raise ldtp.LdtpExecutionError, "Wrong close item type."
             response = ldtp.waittillguinotexist(self.name, '', 20)
             if response == 0:
                 raise ldtp.LdtpExecutionError, "Mmm, something went wrong when closing the application."
-        except ldtp.LdtpExecutionError:
-            raise ldtp.LdtpExecutionError, "Mmm, something went wrong when closing the application."
+        except ldtp.LdtpExecutionError, msg:
+            raise ldtp.LdtpExecutionError, "Mmm, something went wrong when closing the application: " + str(msg)
 
     def save(self, save_menu='mnuSave'):
         """
@@ -124,10 +143,26 @@
     def __init__(self):
         Application.__init__(self, gnome_constants.SH_WINDOW)
 
+    def setup(self):
+        self.open()
+
+    def teardown(self):
+        self.exit()
+
+    def cleanup(self):
+        #TODO: it should delete all the "My Personal Keys"
+        pass
+
     def open(self):
-        open_and_check_app(gnome_constants.SH_LAUNCHER, gnome_constants.SH_WINDOW)
+        Application.open_and_check_app(self, gnome_constants.SH_LAUNCHER)
 
     def new_key(self, key_type):
+        """
+        It opens up the list of available new keys, and select the one to create.
+        
+        @type key_type: string
+        @param key_type: The type of key to create. 
+        """
         
         seahorse = ooldtp.context(self.name)
         
@@ -172,6 +207,24 @@
             raise ldtp.LdtpExecutionError, "There was a problem when clicking the continue button."
         
     def new_pgp_key(self, full_name, email, comment, passphrase):
+        """
+        It creates a new PGP key with the default settings.
+
+        TODO: Allow advanced options
+        TODO: Check the list afterwards for the newly created key
+
+        @type full_name: string 
+        @param full_name: Full name to type for the PGP key
+
+        @type email: string 
+        @param email: Email to type for the PGP key
+
+        @type comment: string 
+        @param comment: Comment to type for the PGP key
+
+        @type passphrase: string 
+        @param passphrase: Passphrase to type for the PGP key
+        """
         
         self.new_key(gnome_constants.SH_TYPE_PGP)
 
@@ -219,8 +272,8 @@
             raise ldtp.LdtpExecutionError, "There was a problem when clicking the create button."
        
         try:
-            ldtp.waittillguiexist(gnome_constants.SH_DLG_NEWPGP_PASS)
-            dlg_new_pgp_pass = ooldtp.context(gnome_constants.SH_DLG_NEWPGP_PASS)
+            ldtp.waittillguiexist(gnome_constants.SH_DLG_NEWKEY_PASS)
+            dlg_new_pgp_pass = ooldtp.context(gnome_constants.SH_DLG_NEWKEY_PASS)
         except ldtp.LdtpExecutionError:
             raise ldtp.LdtpExecutionError, "The new pgp key passphrase dialog was not found."
 
@@ -242,13 +295,171 @@
             raise ldtp.LdtpExecutionError, "There was a problem when clicking the OK button."
  
         try:
-            ldtp.waittillguiexist(gnome_constants.SH_DLG_GENERATING_PGP)
-            while ldtp.guiexist(gnome_constants.SH_DLG_GENERATING_PGP) == 1:
+            ldtp.waittillguiexist(gnome_constants.SH_DLG_GENERATING_KEY)
+            while ldtp.guiexist(gnome_constants.SH_DLG_GENERATING_KEY) == 1:
                 ldtp.wait(1)
         except ldtp.LdtpExecutionError:
             raise ldtp.LdtpExecutionError, "The new pgp generating key dialog was not found."
 
 
+    def new_ssh_key(self, description, passphrase, set_up = False, computer = '', login = ''):
+        """
+        It creates a new SSH key with the default settings.
+
+        TODO: Setting up the key is not working yet
+
+        @type description: string 
+        @param description: Description to type in the SSH key
+
+        @type passphrase: string 
+        @param passphrase: Passphrase to type for the SSH key
+
+        @type set_up: boolean 
+        @param passphrase: True, to set up the SSH key
+
+        @type computer: string 
+        @param computer: URL or IP of the computer to set up the key
+        
+        @type login: string
+        @param login: Login to use in the remote computer
+        """
+        
+        self.new_key(gnome_constants.SH_TYPE_SSH)
+
+        try:
+            ldtp.waittillguiexist(gnome_constants.SH_NEWSSH_DLG)
+            dlg_new_ssh = ooldtp.context(gnome_constants.SH_NEWSSH_DLG)
+        except ldtp.LdtpExecutionError:
+            raise ldtp.LdtpExecutionError, "The new key dialog was not found."
+
+        try:
+            txt_field = dlg_new_ssh.getchild(gnome_constants.SH_DLG_NEWSSH_DESC)
+        except ldtp.LdtpExecutionError:
+            raise ldtp.LdtpExecutionError, "The " + gnome_constants.SH_DLG_NEWSSH_DESC + " text field was not found."
+        try:
+            txt_field.settextvalue(description)
+        except ldtp.LdtpExecutionError:
+            raise ldtp.LdtpExecutionError, "There was an error when writing the text."
+
+        if set_up == True:
+            try:
+                btn_create = dlg_new_ssh.getchild(gnome_constants.SH_BTN_NEWSSH_CREATE_AND_SETUP)
+            except ldtp.LdtpExecutionError:
+                raise ldtp.LdtpExecutionError, "The create button at the new PGP key dialog was not found."
+
+        else:
+            try:
+                btn_create = dlg_new_ssh.getchild(gnome_constants.SH_BTN_NEWSSH_CREATE)
+            except ldtp.LdtpExecutionError:
+                raise ldtp.LdtpExecutionError, "The create button at the new PGP key dialog was not found."
+
+        try:
+            btn_create.click() 
+        except ldtp.LdtpExecutionError:
+            raise ldtp.LdtpExecutionError, "There was a problem when clicking the create button."
+      
+ 
+        try:
+            ldtp.waittillguiexist(gnome_constants.SH_DLG_NEWKEY_PASS)
+            dlg_new_key_pass = ooldtp.context(gnome_constants.SH_DLG_NEWKEY_PASS)
+        except ldtp.LdtpExecutionError:
+            raise ldtp.LdtpExecutionError, "The new key passphrase dialog was not found."
+
+        try:
+            ldtp.enterstring(passphrase)
+            ldtp.enterstring("<tab>")
+            ldtp.enterstring(passphrase)
+        except ldtp.LdtpExecutionError:
+            raise ldtp.LdtpExecutionError, "Error entering passphrase."
+ 
+        try:
+            btn_pass_ok = dlg_new_key_pass.getchild(gnome_constants.SH_BTN_PASS_OK)
+        except ldtp.LdtpExecutionError:
+            raise ldtp.LdtpExecutionError, "The OK button at the new key passphrase dialog was not found."
+
+        try:
+            btn_pass_ok.click() 
+        except ldtp.LdtpExecutionError:
+            raise ldtp.LdtpExecutionError, "There was a problem when clicking the OK button."
+ 
+        if set_up == True and login is not None:
+
+            try:
+                ldtp.waittillguiexist(gnome_constants.SH_DLG_SET_UP)
+                dlg_set_up_computer = ooldtp.context(gnome_constants.SH_DLG_SET_UP)
+            except ldtp.LdtpExecutionError:
+                raise ldtp.LdtpExecutionError, "The set up computer dialog was not found."
+
+            try:
+                txt_field = dlg_set_up_computer.getchild(gnome_constants.SH_TXT_SET_UP_LOGIN)
+            except ldtp.LdtpExecutionError:
+                raise ldtp.LdtpExecutionError, "The " + gnome_constants.SH_TXT_SET_UP_LOGIN + " text field was not found."
+            try:
+                txt_field.settextvalue(login)
+            except ldtp.LdtpExecutionError:
+                raise ldtp.LdtpExecutionError, "There was an error when writing the text."
+
+        if set_up == True:
+            try:
+                txt_field = dlg_set_up_computer.getchild(gnome_constants.SH_TXT_SET_UP_COMPUTER)
+            except ldtp.LdtpExecutionError:
+                raise ldtp.LdtpExecutionError, "The " + gnome_constants.SH_TXT_SET_UP_COMPUTER + " text field was not found."
+            try:
+                txt_field.settextvalue(computer)
+            except ldtp.LdtpExecutionError:
+                raise ldtp.LdtpExecutionError, "There was an error when writing the text."
+
+            try:
+                btn_set_up = dlg_set_up_computer.getchild(gnome_constants.SH_BTN_SET_UP)
+            except ldtp.LdtpExecutionError:
+                raise ldtp.LdtpExecutionError, "The set up button was not found."
+
+            try:
+                btn_set_up.click() 
+            except ldtp.LdtpExecutionError:
+                raise ldtp.LdtpExecutionError, "There was a problem when clicking the set up button."
+            
+        try:
+            while ldtp.guiexist(gnome_constants.SH_DLG_CREATING_SSH) == 1:
+                ldtp.wait(1)
+            
+        except ldtp.LdtpExecutionError:
+            raise ldtp.LdtpExecutionError, "The creating key dialog was not found."
+        
+        # It is too fast to grab the main window afterwards
+        ldtp.wait(3)
+
+    def assert_exists_key(self, name, tab_name = gnome_constants.SH_TAB_PERSONAL_KEYS):
+        """
+        It checks that the KEY with description 'description' is
+        part of the keys of the current user
+
+        @type name: string
+        @param name: The name of the key to search
+        
+        @type tab_name: string
+        @param tab_name: The tab name to search for the key.
+        """
+
+        seahorse = ooldtp.context(self.name)
+        try:
+
+            page_list = seahorse.getchild(gnome_constants.SH_TAB_LIST)
+            page_list.selecttab(gnome_constants.SH_TAB_PERSONAL_KEYS)
+            scroll_pane = ldtp.getobjectproperty(self.name, tab_name, 'children')
+            list_keys = ldtp.getobjectproperty(self.name, scroll_pane, 'children')
+            list_keys = list_keys.split(' ')[0]
+            list_keys = seahorse.getchild(list_keys)
+            for i in range(0, list_keys.getrowcount()):
+                current = list_keys.getcellvalue(i, 1)
+                if name in current:
+                    return True
+            
+            return False
+
+        except ldtp.LdtpExecutionError:
+            raise ldtp.LdtpExecutionError, "Error retrieving the list of keys."
+
 class GEdit(Application):
     """
     GEdit manages the Gedit application.
@@ -257,6 +468,45 @@
     def __init__(self):
         Application.__init__(self, gnome_constants.GE_WINDOW)
 
+    def setup(self):
+        self.open()
+
+    def teardown(self):
+        self.exit()
+
+    def cleanup(self):
+        # Exit using the Quit menu 
+        try:
+            try:
+                gedit = ooldtp.context(self.name)
+                quit_menu = gedit.getchild(gnome_constants.GE_MNU_CLOSE)
+            except ldtp.LdtpExecutionError:
+                raise ldtp.LdtpExecutionError, "The quit menu was not found."
+            quit_menu.selectmenuitem()
+        except ldtp.LdtpExecutionError:
+            raise ldtp.LdtpExecutionError, "Mmm, something went wrong when closing the application."
+
+        result = ldtp.waittillguiexist(gnome_constants.GE_QUESTION_DLG,
+                                       guiTimeOut = 2)
+
+        if result == 1:
+            question_dialog = ooldtp.context(gnome_constants.GE_QUESTION_DLG)
+            question_dlg_btn_close = question_dialog.getchild(gnome_constants.GE_QUESTION_DLG_BTN_CLOSE)
+            question_dlg_btn_close.click()
+        
+        try:
+            gedit = ooldtp.context(self.name)
+            new_menu = gedit.getchild(gnome_constants.GE_MNU_NEW)
+        except ldtp.LdtpExecutionError:
+            raise ldtp.LdtpExecutionError, "The new menu was not found."
+        new_menu.selectmenuitem()
+        
+        result = ldtp.waittillguiexist(
+            self.name, gnome_constants.GE_TXT_FIELD)
+        if result != 1:
+            raise ldtp.LdtpExecutionError, "Failed to set up new document."
+        
+
     def write_text(self, text):
         """
         It writes text to the current buffer of the Gedit window.
@@ -311,7 +561,7 @@
         didn't start properly.
 
         """
-        open_and_check_app(gnome_constants.GE_LAUNCHER, gnome_constants.GE_WINDOW)
+        Application.open_and_check_app(self, gnome_constants.GE_LAUNCHER)
 
     def exit(self, save=False, filename=''):
         """

Modified: trunk/desktoptesting/gnome_constants.py
==============================================================================
--- trunk/desktoptesting/gnome_constants.py	(original)
+++ trunk/desktoptesting/gnome_constants.py	Thu Mar 19 12:15:07 2009
@@ -14,7 +14,7 @@
 SU_BTN_CANCEL = "btnCancel"
 
 # GEdit constants (prefix = GE)
-GE_WINDOW     = "frm*-gedit"
+GE_WINDOW     = "frm*gedit"
 GE_TXT_FIELD  = "txt1"
 GE_LAUNCHER   = "gedit"
 GE_SAVE_DLG   = "dlgSave*"
@@ -25,6 +25,8 @@
 GE_QUESTION_DLG_BTN_SAVE_AS = "btnSaveAs"
 GE_QUESTION_DLG_BTN_CLOSE = "btnClosewithoutSaving"
 GE_MNU_QUIT = "mnuQuit"
+GE_MNU_CLOSE = "mnuClose"
+GE_MNU_NEW = "mnuNew"
 
 # Seahorse contants (prefix = SH)
 SH_WINDOW       = "frmPasswordsandEncryptionKeys"
@@ -38,6 +40,19 @@
 SH_DLG_NEWPGP_EMAIL    = "txtEmailAddress"
 SH_DLG_NEWPGP_COMMENT  = "txtComment"
 SH_BTN_NEWPGP_CREATE   = "btnCreate"
-SH_DLG_NEWPGP_PASS     = "dlgPassphraseforNewPGPKey"
+SH_DLG_NEWKEY_PASS     = "dlgPassphrasefor*"
 SH_BTN_PASS_OK         = "btnOK"
-SH_DLG_GENERATING_PGP  = "dlgGeneratingkey"
+SH_DLG_GENERATING_KEY  = "dlgGeneratingkey"
+SH_DLG_CREATING_SSH    = "dlgCreatingSecureShellKey"
+SH_TYPE_SSH            = "Secure Shell Key"
+SH_NEWSSH_DLG          = "New Secure Shell Key" 
+SH_DLG_NEWSSH_DESC     = "txtKeyDescription"
+SH_BTN_NEWSSH_CREATE_AND_SETUP = "Create and Set Up"
+SH_DLG_SET_UP          = "Set Up Computer for SSH Connection"
+SH_TXT_SET_UP_COMPUTER = "txtThehostnameoraddressoftheserver."
+SH_TXT_SET_UP_LOGIN    = "txtLoginName"
+SH_BTN_SET_UP          = "btnSetUp"
+SH_BTN_NEWSSH_CREATE   = "Just Create Key"
+SH_TAB_PERSONAL_KEYS   = "My Personal Keys"
+SH_TAB_LIST            = "ptl0"
+

Modified: trunk/gedit/gedit_chains.py
==============================================================================
--- trunk/gedit/gedit_chains.py	(original)
+++ trunk/gedit/gedit_chains.py	Thu Mar 19 12:15:07 2009
@@ -8,37 +8,19 @@
 from desktoptesting.gnome import GEdit
 from desktoptesting.check import FileComparison, FAIL
 
-try:
-
-    test = GEdit()
-
-    dataXml  = ldtputils.LdtpDataFileParser(datafilename)    
-    oracle = dataXml.gettagvalue("oracle")[0]
-    chain  = dataXml.gettagvalue("string")[0]
-    test_file = strftime("/tmp/" + "%Y%m%d_%H%M%S" + ".txt", gmtime((time())))
-    
-    start_time = time()
-    
-    test.open()
-    test.write_text(chain)
-    test.save(test_file)
-    test.exit()
-
-    stop_time = time()
-    
-    elapsed = stop_time - start_time
-    
-    testcheck = FileComparison(oracle, test_file)
-    check = testcheck.perform_test()
-
-    ldtp.log (str(elapsed), 'time')
-    
-    if check == FAIL:
-        ldtp.logFailures ("Files differ")
-        ldtp.logFailures ("Files differ", False, "fail") 
-
-except ldtp.LdtpExecutionError:
-    raise
-
-
-
+class GEditChain(GEdit):
+    def testChain(self, oracle=None, chain=None):
+        test_file = strftime(
+            "/tmp/" + "%Y%m%d_%H%M%S" + ".txt", gmtime((time())))
+
+        self.write_text(chain)
+        self.save(test_file)
+
+        testcheck = FileComparison(oracle, test_file)
+
+        if testcheck.perform_test() == FAIL:
+            raise AssertionError, "Files differ"
+
+if __name__ == "__main__":
+    gedit_chains_test = GEditChain()
+    gedit_chains_test.run()

Modified: trunk/gedit/gedit_chains.xml
==============================================================================
--- trunk/gedit/gedit_chains.xml	(original)
+++ trunk/gedit/gedit_chains.xml	Thu Mar 19 12:15:07 2009
@@ -1,21 +1,23 @@
 <?xml version="1.0"?>
-<ldtp>
-  <logfile>/dev/null</logfile>
-  <screenshotdir>/tmp/ldtp-screenshots</screenshotdir>
-  <group>
-    <testcaseid>SavedAsciiTestCase</testcaseid>
-    <script>
-      <testcase>SavedAsciiTestCase</testcase>
-      <name>./gedit/gedit_chains.py</name>
-      <data>./gedit/data/ascii_data.xml</data>
-    </script>
-  </group>
-  <group>
-      <testcaseid>SavedUTF8TestCase</testcaseid>
-    <script>
-      <testcase>SavedUTF8TestCase</testcase>
-      <name>./gedit/gedit_chains.py</name>
-      <data>./gedit/data/utf8_data.xml</data>
-    </script>
-  </group>
-</ldtp>
+<suite name="gedit chains">
+  <class>gedit_chains.GEditChain</class>
+  <description>
+    Tests which verify gedit's save file functionality.
+  </description>
+  <case name="Unicode Tests">
+    <method>testChain</method>
+    <description>Test Unicode text saving.</description>
+    <args>
+      <oracle>./gedit/data/utf8.txt</oracle>
+      <chain>This is a japanese string: ååæè - ãããã</chain>
+    </args>
+  </case>
+  <case name="ASCII Test">
+    <method>testChain</method>
+    <description>Test ASCII text saving.</description>
+    <args>
+      <oracle>./gedit/data/ascii.txt</oracle>
+      <chain>This is a very basic string!</chain>
+    </args>
+  </case>
+</suite>

Modified: trunk/report.xsl
==============================================================================
--- trunk/report.xsl	(original)
+++ trunk/report.xsl	Thu Mar 19 12:15:07 2009
@@ -27,10 +27,61 @@
         initInlineHelp();
       }
       registerLaunchpadFunction(onLoadFunction);
+      function ReverseDisplay(d) {
+        if(document.getElementById(d).style.display == "none") { document.getElementById(d).style.display = "block"; }
+        else { document.getElementById(d).style.display = "none"; }
+      }
     </script>
         <link rel="shortcut icon" href="https://edge.launchpad.net/@@/launchpad.png"/>
       </head>
       <body id="document" class="tab-bugs onecolumn">
+        <div id="locationbar">
+          <div id="logincontrol">
+            <a href="https://bugs.edge.launchpad.net/bugs/bugtrackers/+login";>Log in / Register</a>
+          </div>
+          <form id="globalsearch" action="https://edge.launchpad.net/+search"; xml:lang="en" lang="en" dir="ltr" method="get" accept-charset="UTF-8">
+            <img src="https://edge.launchpad.net/@@/search.png"; style="margin-bottom: -4px" alt="Search launchpad:"/>
+            <input type="search" id="search-text" name="field.text"/>
+          </form>
+          <div id="lp-hierarchy" class="home">
+            <a href="/" class="breadcrumb">
+              <img alt="Launchpad" src="https://edge.launchpad.net/@@/launchpad-logo-and-name-hierarchy.png"/>
+            </a>
+          </div>
+          <div id="globalheader" xml:lang="en" lang="en" dir="ltr">
+            <div class="sitemessage">This site is running pre-release code. <a href="https://edge.launchpad.net/launchpad/+filebug";>Please report all bugs.</a></div>
+          </div>
+          <div class="apps-separator">
+            <!-- -->
+          </div>
+          <div id="lp-apps" class="clearfix">
+            <!-- :-) -->
+            <span class="overview">
+              <a href="https://edge.launchpad.net/";>Launchpad Home</a>
+            </span>
+            <small> / </small>
+            <span class="branches" title="The Code Bazaar">
+              <a href="https://code.edge.launchpad.net/";>Code</a>
+            </span>
+            <small> / </small>
+            <span class="bugs active">
+              <a href="https://bugs.edge.launchpad.net/";>Bugs</a>
+            </span>
+            <small> / </small>
+            <span class="specifications" title="Launchpad feature specification tracker.">
+              <a href="https://blueprints.edge.launchpad.net/";>Blueprints</a>
+            </span>
+            <small> / </small>
+            <span class="translations">
+              <a href="https://translations.edge.launchpad.net/";>Translations</a>
+            </span>
+            <small> / </small>
+            <span class="answers" title="Launchpad Answer Tracker">
+              <a href="https://answers.edge.launchpad.net/";>Answers</a>
+            </span>
+          </div>
+        </div>
+        <!--id="locationbar"-->
         <div id="mainarea">
           <div id="container">
             <!--[if IE 7]>&nbsp;<![endif]-->
@@ -47,30 +98,41 @@
                   This are the results from a run of GNOME Desktop Tests. <br/>
                   If you find false positives, please, report bugs against <a href="https://launchpad.net/gnome-desktop-testing/+filebug";>gnome-desktop-testing</a> project.
               </p>
+              <h2><b>Suite: <xsl:value-of select="suite/@name" /></b> (Class: <xsl:value-of select="suite/class" />)</h2>
+              <h2>Description: <xsl:value-of select="suite/description" /></h2>
+              <br /> 
               <table width="100%" class="sortable listing" id="trackers">
                 <thead>
                   <tr>
-                    <th>Test Name</th>
-                    <th>Script Name</th>
+                    <th>TestCase Name</th>
+                    <th>Description</th>  
+                    <th>Method</th>
                     <th>Status</th>
                     <th>Time Elapsed (s)</th>
-                    <th>Error</th>
+                    <th>Message</th>
                     <th>Screenshot</th>
+                    <th>Stacktrace</th>
                   </tr>
                 </thead>
                 <tbody>
-                  <xsl:for-each select="descendant::group">
-                    <xsl:for-each select="child::script/child::test">
+                    <xsl:for-each select="descendant::case">  
                       <tr>
                         <td>
                           <xsl:value-of select="@name"/>
                         </td>
                         <td>
-                          <xsl:value-of select="ancestor::script[last()]/@name"/>
+                          <xsl:value-of select="child::description"/>
+                        </td>
+                        <td>
+                          <xsl:value-of select="child::method"/>
                         </td>
+                        <xsl:for-each select="descendant::result">  
                         <xsl:choose>
+                          <xsl:when test="child::error/child::text() = 1">
+                            <td><font color="red">Script Error</font></td>
+                          </xsl:when>
                           <xsl:when test="child::pass/child::text() = 0">
-                            <td><font color="red">Failed</font></td>
+                            <td><font color="red">Test Failed</font></td>
                           </xsl:when>
                           <xsl:otherwise>
                             <td><font color="green">Passed</font></td>
@@ -80,17 +142,25 @@
                             <xsl:value-of select="child::time/child::text()"/>
                         </td>
                         <td>
-                          <xsl:if test="child::pass/child::text() = 0">
-                              <xsl:value-of select="child::error/child::text()"/>
-                          </xsl:if>
+                            <xsl:value-of select="child::message/child::text()"/>
                         </td>
                         <td>
-                          <xsl:if test="child::pass/child::text() = 0">
                             <xsl:apply-templates select="child::screenshot" mode="link"/>
-                          </xsl:if>
                         </td>
+                        <td>
+                            <xsl:if test="child::pass/child::text() != 1">
+                                <xsl:call-template name="stacktemplate">
+                                    <xsl:with-param name="stackid">
+                                        <xsl:value-of select="translate(../@name, ' ', '_')" />
+                                    </xsl:with-param>
+                                    <xsl:with-param name="stacktext">
+                                        <xsl:value-of select="child::stacktrace/child::text()" />
+                                    </xsl:with-param>
+                                </xsl:call-template>
+                            </xsl:if>
+                        </td>
+                        </xsl:for-each>
                       </tr>
-                    </xsl:for-each>
                   </xsl:for-each>
                 </tbody>
               </table>
@@ -118,6 +188,17 @@
     <a href="{text()}">
       <xsl:value-of select="text()"/>
     </a>
-    <xsl:text> </xsl:text>
   </xsl:template>
+  <xsl:template name="stacktemplate">
+      <xsl:param name="stackid" />
+      <xsl:param name="stacktext" />
+      <a href="javascript:ReverseDisplay('{$stackid}')">
+          [Show/Hide Stacktrace]
+      </a>
+      <div id="{$stackid}" style="display:none;">
+       <pre>
+          <xsl:value-of select="$stacktext" />
+      </pre>
+      </div>
+ </xsl:template>
 </xsl:stylesheet>

Modified: trunk/seahorse/generate_pgp.py
==============================================================================
--- trunk/seahorse/generate_pgp.py	(original)
+++ trunk/seahorse/generate_pgp.py	Thu Mar 19 12:15:07 2009
@@ -4,32 +4,15 @@
 
 from desktoptesting.gnome import Seahorse
 
-try:
-  
-    dataXml  = ldtputils.LdtpDataFileParser(datafilename)    
-    name     = dataXml.gettagvalue("name")[0]
-    email    = dataXml.gettagvalue("email")[0]
-    comment  = dataXml.gettagvalue("comment")[0]
-    passphrase  = dataXml.gettagvalue("passphrase")[0]
-
-    
-    seahorse = Seahorse()
-    
-    start_time = time()
     
-    # Open the update manager and check the repositories
-    seahorse.open()
-    seahorse.new_pgp_key(name, email, comment, passphrase)
-    seahorse.exit()
+class SeahorsePGP(Seahorse):
+    def test_generate_pgp(self, name, email, comment, passphrase):
         
-    stop_time = time()
- 
-    elapsed = stop_time - start_time
-    
-    ldtp.log (str(elapsed), 'time')
-    
-except ldtp.LdtpExecutionError, msg:
-    raise
+        # Open the update manager and check the repositories
+        self.new_pgp_key(name, email, comment, passphrase)
+
+        if self.assert_exists_key(name) == False:
+            raise AssertionError, "The key was not succesfully created."
 
 
 

Modified: trunk/seahorse/generate_pgp.xml
==============================================================================
--- trunk/seahorse/generate_pgp.xml	(original)
+++ trunk/seahorse/generate_pgp.xml	Thu Mar 19 12:15:07 2009
@@ -1,13 +1,18 @@
 <?xml version="1.0"?>
-<ldtp>
-  <logfile>/dev/null</logfile>
-  <screenshotdir>/tmp/ldtp-screenshots</screenshotdir>
-  <group>
-    <testcaseid>GenerateKeys</testcaseid>
-    <script>
-      <testcase>GeneratePGPKey</testcase>
-      <name>./seahorse/generate_pgp.py</name>
-      <data>./seahorse/data/generate_pgp.xml</data>
-    </script>
-  </group>
-</ldtp>
+<suite name="Generate PGP Keys">
+  <class>generate_pgp.SeahorsePGP</class>
+  <description>
+    Test that generates a PGP file
+  </description>
+  <case name="Generate PGP">
+    <method>test_generate_pgp</method>
+    <description>Generates a PGP key with default options</description>
+    <args>
+      <name>Tester Tester</name>
+      <email>tester testworld org</email>
+      <comment>This is a test</comment>
+      <passphrase>passphrase</passphrase>
+    </args>
+  </case>
+</suite>
+

Added: trunk/seahorse/generate_ssh.py
==============================================================================
--- (empty file)
+++ trunk/seahorse/generate_ssh.py	Thu Mar 19 12:15:07 2009
@@ -0,0 +1,15 @@
+import ldtp 
+import ldtputils 
+from time import time 
+
+from desktoptesting.gnome import Seahorse
+
+class SeahorseSSH(Seahorse):
+    def test_generate_ssh(self, description, set_up, passphrase, computer='', login=''):
+        # Create the new key
+        self.new_ssh_key(description, set_up, passphrase, computer, login)
+
+        # Check that the key was successfully created
+        if self.assert_exists_key(description) == False:
+            raise AssertionError, "The key was not succesfully created."
+

Added: trunk/seahorse/generate_ssh.xml
==============================================================================
--- (empty file)
+++ trunk/seahorse/generate_ssh.xml	Thu Mar 19 12:15:07 2009
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<suite name="Generate SSH Keys">
+  <class>generate_ssh.SeahorseSSH</class>
+  <description>
+    Test that generates a SSH key
+  </description>
+  <case name="Generate SSH">
+    <method>test_generate_ssh</method>
+    <description>Generates a SSH key with default options</description>
+    <args>
+        <description>This is a test</description>
+        <set_up>False</set_up>
+        <passphrase>passphrase</passphrase>
+    </args>
+  </case>
+</suite>
+
+
+



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]