How do I verify existence of a control without throwing an error?

17 posts, 0 answers
  1. Philip
    Philip avatar
    10 posts
    Member since:
    Sep 2010

    Posted 15 Nov 2010 Link to this post

    I am interested to know how to verify whether or not a control exists on a web page without throwing an error.

    For instance, when I click Button A, Button B is created, but until created, Button B doesn't exist. How would I check to see if Button B exists without failing if it does not?

    I have tried Verify Exists & Verify ExistsNot, but both fail with an "Unable to locate element" and fail the entire test.

    Please help.
  2. Stoich
    Admin
    Stoich avatar
    1 posts

    Posted 16 Nov 2010 Link to this post

    Hi Philip,

     instead of using Verify, use Wait (also found in Quick Tasks).

    For instance: if a Button takes 10 seconds to appear "Wait - element exists" will wait until the element appears before the test moves on to the next step. Verify on the other hand would fail immediately because the element doesn't exist at the time of the verification. 

    Something else you can do is set your Verify step to "Continue on Failure" from the Steps View (see the attached screenshot). This will continue executing the rest of the test even if your Verify step fails. 

    I hope I've managed to answer your question!

    Kind regards,
    Stoich
    the Telerik team
    See What’s New in WebUI Test Studio’s Q3 Release – Friday, November 19th, 2010 at 11am EST – Register Today!
  3. Philip
    Philip avatar
    10 posts
    Member since:
    Sep 2010

    Posted 16 Nov 2010 Link to this post

    Your suggested solution does not work for the following reasons.

    The button isn't taking 10 seconds to appear. If it isn't there when the page has finished loading it WON'T be. Trying to do both "Wait.ForExists" and "Wait.ForExistsNot" both result in a failure being thrown when the control isn't there as shown below.
    Failure Information:
    ~~~~~~~~~~~~~~~
    Exception thrown executing coded step: '[oldLogin_IfSelect_DoThis] : If PossibleSelectControl exists, select index 0 to cause it to be replaced by a text control'.
    InnerException:
    System.TimeoutException: Wait for condition has timed out
       at ArtOfTest.Common.WaitSync.CheckResult(WaitSync wait, String extraExceptionInfo)
       at ArtOfTest.Common.WaitSync.For[T,V](Func`3 func, T target, V custom, Boolean invertCondition, Int32 timeout)
       at ArtOfTest.WebAii.Synchronization.Wait.ForCondition(Func`3 condition, Boolean invertCondition, Object custom, Int32 timeout)
       at ArtOfTest.WebAii.Synchronization.Wait.ForExists(Int32 timeout, Boolean refreshElement)
       at ArtOfTest.WebAii.TestTemplates.HtmlElementContainer.Get(HtmlFindExpression expr, Boolean waitOnElement, Int32 timeout)
       at ArtOfTest.WebAii.TestTemplates.HtmlElementContainer.Get(HtmlFindExpression expr)
       at ArtOfTest.WebAii.TestTemplates.HtmlElementContainer.Get[TControl](HtmlFindExpression expr)
       at ArtOfTest.WebAii.TestTemplates.HtmlElementContainer.Get[TControl](String[] clauses)
       at CalendarTry1.Pages.WorkspaceLoginPage.get_LoginlistSelect() in c:\Documents and Settings\username\My Documents\WebUI Test Studio Projects\CalendarTry1\Pages.g.cs:line 73
       at CalendarTry1.oldLogin.oldLogin_IfSelect_DoThis() in c:\Documents and Settings\username\My Documents\WebUI Test Studio Projects\CalendarTry1\oldLogin.aii.cs:line 137
    ------------------------------------------------------------
    '11/16/2010 9:39:58 AM' - Detected a failure. Step is marked 'ContinueOnFailure=True' continuing test execution.

    But the biggest reason that this fails to work is that when a single step fails, the entire test fails. The "Continue On Failure" doesn't change the fact that the test itself reports a failure as shown below.
    '11/16/2010 9:39:58 AM' - Detected a failure. Step is marked 'ContinueOnFailure=True' continuing test execution.
    '11/16/2010 9:39:59 AM' - 'Pass' : 3. [oldLogin_SetCredentials] : Set credentials for login.
    '11/16/2010 9:40:04 AM' - 'Pass' : 4. Click 'LoginSubmit'
    '11/16/2010 9:40:04 AM' - 'Pass' : 5. Verify 'TextContent' 'Contains' 'Logged in as: myName' on 'LoggedInAsSpan'
    ------------------------------------------------------------
    '11/16/2010 9:40:04 AM' - Overall Result: Fail
    '11/16/2010 9:40:04 AM' - Duration: [0 min: 10 sec: 484 msec]
    ------------------------------------------------------------
    '11/16/2010 9:40:05 AM' - Test completed!

    Is there any way around these hurdles?
  4. Stoich
    Admin
    Stoich avatar
    1 posts

    Posted 17 Nov 2010 Link to this post

    Hello Philip,

      I'm sorry this solution didn't work for you - I misunderstood what you were trying to do. 

    That being said, it seems what you need is Conditional Logical Statements.
    Basically, you can do this:
    If (element X exists) { do something } 
    And then you can add this at any point in the test where you think the element x is likely to appear. And it won't fail if the element isn't there, it will just keep going. 

    Another similar solution:
    while (element X does not exist) { keep doing something or just waiting } 
    This will keep doing something or waiting until the element appears and will not time out or fail (though you probably will want it to time out at some point). 

    The best part is that you don't need to write any code to implement this stuff. I don't know whether you are aware but we've just released our Q3 release of WebUI Test Studio. One of the new features is adding Logical Statements from the UI without writting any code. 

    Ok, so first you need to get the Q3 release of WebUI Test Studio: 
    QA --> http://www.telerik.com/account/your-products/trial-product-versions/trial-single-download.aspx?pmvid=2313&pid=741

    Dev--> http://www.telerik.com/account/your-products/trial-product-versions/trial-single-download.aspx?pmvid=0&pid=740

    Install it right over your current version - it should be fine.

    Once you have it check out the blog post on the new Conditional Logical Statements feature: 
    http://blogs.telerik.com/testing/posts/10-11-08/q3_2010_-_creating_if_else_statements_with_webui_test_studio.aspx

    Don't miss the video tutorial: http://tv.telerik.com/watch/automated-testing-tools/conditional-logic-ifelse-statement-webui-test-studio  --> I'm confident this will give you a very good idea how to use the feature in your own test: in the video they use the IF statement to check whether a text box contains "1" but it works exactly the same way with "Verify" and you can remove your Else statement if you don't need to do anything if the Element hasn't appeared.

    Of course you can also implement this in WebUI Test Studio Dev Edition by adding Coded Steps and writting the logic yourself but it won't be any quicker or easier. 

    Please let me know whether this solution works for you!

    Regards,
    Stoich
    the Telerik team
    See What’s New in WebUI Test Studio’s Q3 Release – Friday, November 19th, 2010 at 11am EST – Register Today!
  5. Philip
    Philip avatar
    10 posts
    Member since:
    Sep 2010

    Posted 17 Nov 2010 Link to this post

    Stoich,

    Thank you for your assistance thus far, and let me explain the issue more clearly. You stated in your reply:
    Basically, you can do this:
    If (element X exists) { do something }
    And then you can add this at any point in the test where you think
    the element x is likely to appear. And it won't fail if the element
    isn't there, it will just keep going.
    Unfortunately, in my second reply I state that "...and it won't fail if the element isn't there..." is exactly the part that isn't working correctly. It fails, and I even pasted the error thrown in the log within my reply.

    Just to be perfectly clear, I have attempted the following different ways of "if (element x exists)" and they all throw failures when the control cannot be found:
    Verify.Exists
    Verify.ExistsNot
    Wait.Exists
    Wait.ExistsNot

    If there is another way of doing the "if (element x exists)" please do let me know.
  6. Cody
    Admin
    Cody avatar
    3354 posts

    Posted 18 Nov 2010 Link to this post

    Hi Philip,

    Let me interject and see if I understand exactly what you're trying to accomplish. Is the following correct?

    • You want to verify whether or not an element exists
    • If the element does exist do nothing
    • If the element does not exist, log it and do nothing
    • The test is marked Passed whether or not the element exists
    Do I have all the conditions correct? If so, I must admit this cannot be done using a normal verification or wait for step. We normally don't consider this to be best practice. We recommend writing a test that expects it to be present and will fail the test when not present and a separate test for the vice versa. We also recommend using the "Continue on failure" feature for those verification steps where you don't want the test to abort just because the verification did not pass. The test will still be marked failed overall (even though it did run to completion) with that specific verification step marked fail. We recommend this as best practice such that at a glance you can tell if anything went wrong within the test.

    If the test is marked Passed but the verification actually failed within the test, it's too easy overlook that little detail. We prefer to see "Test Failed" if any verification failed for any reason whatsoever.

    To accomplish your combination can be done bug requires a coded step. Let's assume I have a Verify Element Exists test step as shown in the attached screen shot. Convert that step to code and then wrap it in a try-catch block like this:

    try
    {
        // Wait for Exists 'DeveloperLink'
        Pages.TelerikBing.DeveloperLink.Wait.ForExists(10000);
        Log.WriteLine("PASS: The element was found");
    }
    catch (TimeoutException)
    {
        Log.WriteLine("FAIL: The element was not found");
    }

    This this sample you will get a log entry in the tests log, but the test will always be marked Pass no matter what the result of the element verification actually is.

    Regards,
    Cody
    the Telerik team
    See What’s New in WebUI Test Studio’s Q3 Release – Friday, November 19th, 2010 at 11am EST – Register Today!
  7. Philip
    Philip avatar
    10 posts
    Member since:
    Sep 2010

    Posted 18 Nov 2010 Link to this post

    Cody,

    Now we've come full circle back onto the original function I was trying to do, to verify existence of a control without throwing an error (it's even the title of the original post). The reason that I did not want to throw an error was because the existence of the control is used to determine which of two logic paths the test should take, and here is why.

    In Application X, there is a Log In screen. A user coming to the page for the first time is greeting with text inputs for both the user name and password fields. If the user has visited the log in page before and logged in successfully, they are greeted by a select control in place of the user name text control already filled with the name used the last time they logged in, and filled with any other names they've successfully logged in with.

    I was attempting to use your product to devise a test that would interface with either the text control or the select control, depending on which control was present; and since your product can run tests through IE, Firefox & Chrome on windows each browser would be set up with a different initial state.

    So, armed with the knowledge that I've gained through the several answers here, I need to answer the original question. I now know that I can use a try {} catch (error) {} to suppress the error message. Understanding the scenario that I have described above, would that mean that I would need to couch any logic that required the testing of whether a control doesn't exist in such a try...catch block? And this would also mean that I would be unable to use the "Logical" functionality as both IF...ELSE and WHILE...LOOP don't accept coded steps as their logic "switch"?

    Thank you for your continued assistance.
  8. Cody
    Admin
    Cody avatar
    3354 posts

    Posted 19 Nov 2010 Link to this post

    Hi Philip,

    I apologize it has taken so many rounds to get you a straight answer to your automation problem. Thank you for taking the extra time to explain in detail what you are trying to accomplish. See if I better understand it now. You want to:

    • Navigate to your web page
    • Perform some steps (such as login)
    • If an element exists on the page, do block A, else do block B
    • Do some more steps after the If Else block

    Do I have the sequence correct now?

    One technical problem we do have with the product is that trying to use a Verify Element Exists (or Not Exists) in an If Else block currently does not work as desired. It will abort the test if the element does not exist. This was a deliberate design decision by the development team. It was their goal to make text compares work with the If Else, but cause the test to abort of the element you wanted to test the text of didn't exist. The side effect of this is you can't use an Verify Exists in the If Else block. I believe this is the problem you are actually running in to.

    Is there some other element that will always exist in both cases in which you can compare the value of? Or perhaps the property of some element that will always exist? This does work now with the If Else block.

    The alternatives I can think of are:

    • Don't use the If Else block. Have two separate tests, one for each case.
    • Implement the If Else and the steps inside of them 100% within a single coded step.

    We'll be happy to assist with either approach. Let us know and we'll help you as/when needed.

    In addition I am going to bring this matter up with our CTO and explain how a critical test case such as yours is seriously broken with their current implementation. Hopefully we'll come up with a better solution in a near future release. I will update you with the outcome of that discussion.

    Thank you for your patience as we work to improve our product and make it the best web application testing tool available on the market.

    Regards,
    Cody
    the Telerik team
    See What’s New in WebUI Test Studio’s Q3 Release – Friday, November 19th, 2010 at 11am EST – Register Today!
  9. Avraham
    Avraham avatar
    4 posts
    Member since:
    Nov 2010

    Posted 16 Dec 2010 Link to this post

    Folks,
    I have just spent a couple of hours trying to do something that i consider the ABC of QA Automation and, i think, is along the same line of Philip's issue.

    I have a Log In script - the epitome of simplicity.
    My web app always have some control that is visible on the top span of the page (say, Logout link)
    I want to do something VERY simple, namely, place the body of the script in an IF...ELSE construct.
    IF <TheLogout Control Does Not Exist> THEN
        navigate to the homepage
        login
        verify homepage is displayed
    ELSE

    In my experience of the past couple of hours (this is without writing code)
    1. If i use Verify ExistNot - test fails on some exception (see indented text);

        Overall Result: Fail
        ------------------------------------------------------------
        '12/16/2010 6:09:18 PM' - Starting execution....
        ------------------------------------------------------------
        '12/16/2010 6:09:27 PM' - 'Fail' : 1. IF (Verify element 'Home Link' 'is not' visible.) THEN
        '12/16/2010 6:09:27 PM' - Unable to determine logical branch to go into. Unable to execute verification.
        ------------------------------------------------------------
        Failure Information: 
        ~~~~~~~~~~~~~~~
        Unable to locate element. Details: Attempting to find [Html] element using 
        Find logic 
         (Html): [tagname 'Exact' a] AND [TextContent 'Exact' Home]

        Unable to locate element. Search failed!

        ------------------------------------------------------------
        '12/16/2010 6:09:27 PM' - Detected a failure. Step is marked 'ContinueOnFailure=True' continuing test execution.
        ------------------------------------------------------------
        '12/16/2010 6:09:27 PM' - Overall Result: Fail
        '12/16/2010 6:09:27 PM' - Duration: [0 min: 6 sec: 427 msec]
        ------------------------------------------------------------
        '12/16/2010 6:09:28 PM' - Test completed!

    2. If i use Wait ExistNot - the condition fails and the login body is always executed.

    In most other QA Automation tools this is very easy to do.

    I think it is a MUST FIX

  10. Cody
    Admin
    Cody avatar
    3354 posts

    Posted 17 Dec 2010 Link to this post

    Hello Avraham,

    We agree 100%. In fact if you upgrade to our SP1 release, 2010.3.1213 you should find this now works as expected.

    All the best,
    Cody
    the Telerik team
    Interested in Agile Testing? Check out Telerik TV for a recording of Automated Testing in the Agile Environment
  11. Filip
    Filip avatar
    5 posts
    Member since:
    Jan 2011

    Posted 20 Jan 2011 Link to this post

    Hi

    After I read all that I'm still having problems achieving 1 simple thing: 

    After I perform an action (let's say a button click) I would like to ensure that a TextBlock doesn't exist on Silverlight page. Before the click the TextBlock never existed on the page and after the click I would like to wait exactly 0.5s to ensure it still doesn't exist. 

    I thought I should use MyTextBlock.Wait.ForExistsNot(500) however it doesn't seem to work if the TextBlock never existed (exception thrown).

    The trick with try/catch would work for me except the fact that I cannot precisely control the wait time.

    Any solutions?

  12. ME
    ME avatar
    13 posts
    Member since:
    Dec 2010

    Posted 20 Jan 2011 Link to this post

    Philip,
    Not being an expert and having struggled with the same issue (except, i avoid coding like a plague), here's my understanding and how i resolve it (credits to Cody).
    You begin by creating the situation where the control / widget DOES exist and create a "Wait Exists" on it.
    (my understanding is that) this is when Telerik places the control in the repository so it can later be referenced.
    In my humble opinion - this should do it.
    If this still does not work then you may have repository issues similar to those created in mine - due to ignorance.

    Bey
  13. Philip
    Philip avatar
    10 posts
    Member since:
    Sep 2010

    Posted 20 Jan 2011 Link to this post

    ME,

    Sadly, your fix is moot in my case. I cannot "create the situation where the control DOES exist" with regards to the test.

    I understand this to be "works as designed" with regards to the developers at Telerik. If you go up a few posts you'll see Cody from The Telerik Team's response as they, if I'm paraphrasing it correctly, chose abort when making a comparison in an IF .. ELSE block as a design decision. Until this stance changes, the problem will continue to require a convoluted workaround. Unfortunately, if memory serves (my trial has expired and I've been unable to extend it; another issue but not relevant to the current topic) that portion is also moot because even if you do use the convoluted coded step to allow you to step into the section of the test you want to, the failure is still a failure (even though it's captured within the step and dealt with) and causes the entire test to report a failure anyway.

    So, for the original question of "How do I verify (non)existence of a control without throwing an error?" the simple answer is "You can't."

    ~ Philip

    P.S. I do appreciate the suggestion, though.
  14. ME
    ME avatar
    13 posts
    Member since:
    Dec 2010

    Posted 20 Jan 2011 Link to this post

    I fully understand and had a recent conversation with one of the support people indicating - along the lines you argue - that, whether a control is in the repository or not, the exists / not exists (applied to a page or a control) should work correctly - as opposed to according to Telerik's preference of implementation.
    I did not get too far with this argument.
  15. Cody
    Admin
    Cody avatar
    3354 posts

    Posted 21 Jan 2011 Link to this post

    @Filip Czaja 

    Thank you for alerting us of this problem. It is indeed a bug that MyTextBlock.Wait.ForExistsNot(500) will always throw an exception. I have fuiled bug 105454 to track this problem.

    The good news is that a non-coded Wait For Exists Not step does work as expected. Also you can use a like of code like this to do the same thing:

    Assert.IsNull(ActiveBrowser.Find.ByExpression(new HtmlFindExpression("src=http://col.stb.s-msn.com/i/B7/EB75D45B8948F72EE451223E95A96.gif", "tagname=img")));

    @Philip Antokal
    We have fixed our Wait/Verify For Exists/ Exists Not descriptor so that it now works as expected in an IF ELSE block. You just need the latest version to obtain this behavior.

    We have taken the deliberate approach that any other type of verification (e.g. textblock has certain text string) will abort the test unconditionally if the element that we're looking for to test the property of cannot be found.

    For your specific case, if you cannot ever create a condition that the element does exist, how can we know what element to look for (i.e. what's the find expression going to be for it) so we can really check that it is not present at all? Maybe I'm missing something, but I can't see how can we verify an element is not there if we don't know precisely what to look for in the first place.

    Regards,
    Cody
    the Telerik team
    Interested in Agile Testing? Check out Telerik TV for a recording of Automated Testing in the Agile Environment
  16. satyanarayana
    satyanarayana avatar
    2 posts
    Member since:
    Jan 2013

    Posted 03 May 2013 Link to this post

    HI All,
    similarly i am also facing the same problem i.e .. how can we log multiple Error message in one function. that means Please find the sample code which i need to execute all steps in  each function.

    Code:
    public void Function1()
    {
          string a = "Test";
          string b = "Test1";
         
          if(String.Equals(a,b))
          {
                  Log.Writline("Both the strings are same");
           }
           else
           {
                      Log.Writline(Logtype.Error, "Both the strings are not same");
           }

          Function2();
    }

    public void Function2()
    {
          Log.writeline("Test is in progress");
          Log.writeline(Logtype.Error,"Test is in middle");
          Log.writeline("Test is in Over");
    }

    In the above example i have to execute all lines of code depends on the if condition. please let me know how i can execute complete Function1 and Function2
    Thanks
    satyanarayana
  17. Byron
    Admin
    Byron avatar
    184 posts

    Posted 08 May 2013 Link to this post

    Hi Satyanarayana,

    As you may already know, passing LogType.Error to Log.WriteLine generates a LogErrorException. This causes the step to fail immediately without proceeding to subsequent lines of code.

    One way to address this is to wrap the Log.WriteLine call in a try...catch block. For example:

    Log.WriteLine("Test is in progress");
     
    try
    {
    Log.WriteLine(LogType.Error, "Test is in the middle");
    }
    catch(ArtOfTest.WebAii.Exceptions.LogErrorException){}
     
    Log.WriteLine("Test is in Over");

    This pattern logs all three errors. Please let us know if we can help you further.

    Greetings,
    Byron
    the Telerik team
    Quickly become an expert in Test Studio, check out our new training sessions!
    Test Studio Trainings
Back to Top