Q7 1.3.10 most noticeable improvements

New and Noteworthy, Q7, 15.01.2014 by Ivan Inozemtsev View Comments

Congrtulations on past holidays! On December 23rd we have released Q7 1.3.10 (the full list of resolved issues is available here), and in this post I’d like to describe a three improvements and bugfixes which I personally like the most.

QS-3108 String-indexed properties for assertion

Before Q7 1.3.10, there was no out-of-the box way to assert a Tree/Table item text in a column addressed by name.

Suppose we are testing a Tasks view that it correctly displays automatic tasks created from TODO comments. A script performing these actions might look like this:

with [get-editor "Program.java" | get-text-viewer] {
    set-caret-pos 4 26
    key-type Enter
    type-text "// TODO some task"
}
get-button "Save (M1+S)" | click

Now we need to add assertions that Tasks view shows correct text in its columns. Before 1.3.10 version, these assertions would look like this:

with [get-view Tasks | get-tree | get-item "TODO some task" -column Description] {
    get-property "columns[3]" | equals "Program.java" | verify-true
    get-property "columns[4]" | equals "/sample/src" | verify-true
    get-property "columns[5]" | equals "line 5" | verify-true
}

This code asserts values in columns based on column indices. This is hardly readable and potentially fragile in case column order changes or new column added. Now there’s a property ‘values’, which allows to access values in columns based on column names:

with [get-view Tasks | get-tree | get-item "TODO some task" -column Description] {
    get-property "values['Location']" | equals "line 5" | verify-true
    get-property "values['Path']" | equals "/sample/src" | verify-true
    get-property "values['Resource']" | equals "Program.java" | verify-true

}   

QS-3065 try command does not send ‘catch’ block results into output pipe

This one is really trivial to implement, but was really annoying. Most of ECL commands which accept scripts as arguments (i.e. with, if, foreach) are redirecting an output of passed scripts into its own output thus allowing a composition via pipes:

// ''if command writes to its output the results of 'then' or 'else' branches  
if [$foo | eq "bar"] { emit 1 } -else { emit 2} | str | log

Such pipe redirection is particularly useful to return values from procedures, here’s an example (probably a bit artificial):

proc "get-close-or-open-menu" [val projectItem -input] {
        if [$projectItem | get-property "getData().isOpen()" -raw] {
           $projectItem | get-menu "Close Project"
        } -else {
                $projectItem | get-menu "Open Project"
        }
}

get-view "Package Explorer" | get-tree | get-item sample | get-close-or-open-menu | click

However there was an issue with a try command – in case of successful executionit was correctly sending a body block output into an output, but if body fails, then an output of a catch block was not being redirected. With a fix of this issue, it is possible to create procedures like this:

proc "has-button" [val window -input] [val buttonName] {
     try {
         $window | get-button $buttonName
         emit true
     } -catch {
         emit false
     }
}

get-preferences-menu | click
get-window Preferences | has-button OK | assert-true

QS-3032 Q7 Execution details is not enough to understand what we are waiting for

Automatic waits of asynchronous operations is one of the key features of Q7. However, sometimes when execution stucks waiting for some operation, it is hard to understand exactly what Q7 is waiting for. With a new release, an execution details report includes a complete information which operations were executed and how long. And actually sometimes it is a great fun to take a look what actually goes on during a simple action, like closing a project:

get-view "Package Explorer" | get-tree | select sample | get-menu "Close Project" | click

And here’s what we see in Execution details of a menu click:

*click* time: 0.540 s
      --> q7 wait details <-- total wait time: 525
              async: com.xored.tesla.internal.ui.player.SWTUIPlayer.click:793, total time: 5, ticks: 1 to 1
              job: org.eclipse.ui.actions.WorkspaceAction.runInBackground:490, total time: 24, ticks: 1 to 1
              job: org.eclipse.ui.internal.progress.ProgressManager.scheduled:496, total time: 301, ticks: 1 to 1
              async: org.eclipse.ui.internal.progress.ProgressManager.scheduled:496, total time: 301, ticks: 1 to 1
              async: org.eclipse.ui.progress.UIJob.run:83, total time: 370, ticks: 1 to 1
              async: org.eclipse.ui.internal.PopupMenuExtender.menuAboutToHide:386, total time: 307, ticks: 1 to 1
              async: org.eclipse.ui.internal.progress.ProgressMonitorFocusJobDialog.runAsync:278, total time: 312, ticks: 1 to 1
              job: org.eclipse.core.internal.events.NotificationManager.requestNotify:206, total time: 3, ticks: 1 to 1
              job: org.eclipse.jdt.internal.ui.packageview.PackageExplorerContentProvider.postAsyncUpdate:171, total time: 325, ticks: 1 to 1
              job: org.eclipse.jdt.internal.corext.util.OpenTypeHistory.markAsInconsistent:213, total time: 6, ticks: 1 to 1
              async: org.eclipse.ui.internal.ide.WorkbenchActionBuilder.updateBuildActions:1317, total time: 295, ticks: 1 to 1
              async: org.eclipse.ui.internal.navigator.resources.workbench.ResourceExtensionContentProvider.processDelta:118, total time: 302, ticks: 1 to 1
              job: org.eclipse.ui.internal.views.markers.MarkerUpdateJob, total time: 11, ticks: 1 to 1
              async: org.eclipse.ui.menus.CommandContributionItem.updateCommandProperties:390, total time: 301, ticks: 1 to 1
              async: org.eclipse.jface.action.ActionContributionItem.actionPropertyChange:178, total time: 301, ticks: 1 to 1
              job: org.eclipse.core.internal.events.AutoBuildJob, total time: 5, ticks: 1 to 1
              async: org.eclipse.jdt.internal.ui.packageview.PackageExplorerContentProvider.postAsyncUpdate:171, total time: 321, ticks: 1 to 1
              job: org.eclipse.ui.internal.views.markers.UIUpdateJob, total time: 334, ticks: 1 to 1
              async: org.eclipse.ui.internal.views.markers.UIUpdateJob, total time: 333, ticks: 1 to 1
              sync: org.eclipse.jface.dialogs.IconAndMessageDialog.getSWTImage:289, ticks: 1 to 1
              async: org.eclipse.ui.internal.progress.WorkbenchSiteProgressService$SiteUpdateJob, total time: 209, ticks: 1 to 1
              async: org.eclipse.ui.internal.progress.AnimationManager$1, total time: 208, ticks: 1 to 1
              job: org.eclipse.ui.internal.progress.ProgressMonitorFocusJobDialog.show:464, total time: 62, ticks: 1 to 1
              async: org.eclipse.ui.internal.progress.ProgressMonitorFocusJobDialog.show:464, total time: 62, ticks: 1 to 1
              job: org.eclipse.ui.internal.decorators.DecorationScheduler.decorated:255, total time: 54, ticks: 1 to 1
              async: org.eclipse.ui.internal.decorators.DecorationScheduler.decorated:255, total time: 54, ticks: 1 to 1
              job: org.eclipse.ui.internal.progress.TaskBarProgressManager.setAnimated:288, total time: 359, ticks: 1 to 2
              async: org.eclipse.ui.internal.progress.TaskBarProgressManager.setAnimated:288, total time: 359, ticks: 1 to 2
              job: org.eclipse.ui.internal.decorators.DecorationScheduler.decorated:255, total time: 15, ticks: 6 to 6
              async: org.eclipse.ui.internal.decorators.DecorationScheduler.decorated:255, total time: 15, ticks: 6 to 6
              async: org.eclipse.ui.progress.UIJob.run:83, ticks: 6 to 6
              async: org.eclipse.ui.internal.progress.WorkbenchSiteProgressService$SiteUpdateJob, total time: 11, ticks: 9 to 9
              async: org.eclipse.ui.progress.UIJob.run:83, total time: 3, ticks: 9 to 9
              async: org.eclipse.ui.internal.progress.AnimationManager$1, total time: 8, ticks: 9 to 9
              job: org.eclipse.ui.internal.decorators.DecorationScheduler.queueForDecoration:159, total time: 205, ticks: 1 to 13
              decorator: org.eclipse.ui.internal.decorators.DecorationScheduler.queueForDecoration:159, total time: 141, ticks: 2 to 13

Wow! What takes just two clicks for a user and one line of ECL code in Q7 test case, in fact spawns a complex chain of operations involving invocation of 13 Eclipse jobs and 21 async Display execs. And we can see a source location of all these operations and understand how much time it took. Our next step in this direction is going to be to give an ability to ignore waiting of some of these operations via ECL commands. This might be useful when user wants to test some operation canceling or there are some long-running background operations which are not actually affect user actions.

blog comments powered by Disqus

Functional and UI Testing for Eclipse-based Applications

Test automation solution, handcrafted for Eclipse. Modern and easy to learn IDE.

Product Health Analytics and Support Automation Platform

End-user and product analytics solution that gives you rich insights into your application health & performance.

Eclipse-based IDE for the Fantom Programming Language

Full-featured Integrated Development Environment for emerging Fantom programming language.