Forum Discussion

abrar22's avatar
abrar22
Frequent Contributor
9 years ago

Wait for Element until its exists

Hi, 

 

Is there any specific method which I can use to wait until a certain element exists or loads up only then it goes to next step. As currently I am using .Delay() method which can fail if element takes more time than time given in Delay.

 

Thanks

 

  • djadhav's avatar
    djadhav
    Regular Contributor

    I have found best results using WaitChild or WaitAliasChild(if you use NameMapping Aliases).

    Directly checking Exists on an object throws an error while Delay() will always add fixed additonal time to the script while running.

     

    WaitChild over comes both of these issues.

     

    Here is more information on WaitChild: https://support.smartbear.com/viewarticle/72783/

    • NisHera's avatar
      NisHera
      Valued Contributor

       

      Also be aware that even though some objects exists may not visible
      in which case TC coulc not use or operate the object
      It is usefull in some case check visible or VisibleOnScreen is true
      along with Exists see this

      • abrar22's avatar
        abrar22
        Frequent Contributor

        Hi,

         

        Thanks for you replies.


        So I have WBtn_ABC in ny Name mapping (Aliases.Product.TransitionBox.PriceTicker.WBtn_ABC)

         

        Can i just use 

         

        (WBtn_ABC.Exists &&WBtn_ABC.VisibleOnScreen)

         

        ?

         

        Thanks

        A

  • function CheckPropertyExists(ObjPropNameArray:OleVariant,ObjPropValuesArray:OleVariant,DispMsg:OleVariant=nil,Parent:OleVariant=nil,WaitTime:OleVariant=nil,IsLogError:boolean=true):boolean;
    var
      objToChk : OleVariant;
      i:integer;
      warningTxt,propName,propVal:string;
    begin
      try
        try
            if IsNullNil(DispMsg) then
                    DispMsg := 'Waiting for the object to appear on the screen';
          Indicator.Show;
          Indicator.PushText(TidyString(DispMsg));
          objToChk := Utils.CreateStubObject;
          if IsNullNil(Parent) then
          begin
            Parent := LOTS_Main_GetLotsParentObj;
            if not Parent.exists then exit;
          end;    
          
          if IsNullNil(WaitTime) then
          begin
            WaitTime := Project.Variables.WaitTime;
          end
          else
            WaitTime := VarToInt(WaitTime);    
          
         for  i : = 0 to  WaitTime/1000 do
         begin
            if not Parent.exists then break;
            objToChk := Parent.FindChild(ObjPropNameArray,ObjPropValuesArray,1000,false);
            Parent.Refresh;      
            if ((objToChk.Exists) and (objToChk.Visible)) then  break;
            aqUtils.Delay(2000,Indicator.Text);
         end;   
          
         //check to see if the property is visivle on screen
         {if  objToChk.Exists then
         begin
            if not objToChk.VisibleOnScreen then
              Log.Warning('The object exists but is not visible on screen');
         end;}
                  
         for i := VarArrayHighBound(ObjPropNameArray, 1) downto 0 do
        begin
          propName :=  #13#10+propName+' Property Name ' + TidyString(i+1)  +':  '+ TidyString(ObjPropNameArray[i])+'   '+#13#10;
          propVal :=  #13#10+propVal+' Property Value ' + TidyString(i+1) + ':  ' +TidyString(ObjPropValuesArray[i])+'   '+#13#10;
        end;
        warningTxt := 'Unable to find the propety with Property Details' + #13#10
                                + 'Object Property Names : ' + #13#10 
                                + propName + #13#10 + 
                                + 'Object Property Values : ' + #13#10
                                +propVal + #13#10
                                +' Total Delay Used : ' + TidyString(WaitTime);             
        except
          Log.Error('Exception in CheckPropertyExists routiene,click on addtional Information tab for details... ',exceptionmessage);
        end;
      finally
         if not objToChk.Exists  then
         begin
            if IsLogError then
            begin
                Log.Error('Failed to find the Property,click on addtional Information tab for details... ' ,warningTxt,300,nil,Sys.Desktop.Picture());           
            end;    
             result := false;
         end
         else
         begin      
            result := true;    
        end;      
        Indicator.PopText();
      end;  
    end;
    • marinb's avatar
      marinb
      Contributor

      Kinda using something like this in many of my scripts (jscript), which works like a charm and you're able to give a maximum waiting time.

       

       

      function WaitForObject(Object, MaxWait)
      { 
        for (var i=0;i<MaxWait;i++)
        {
          if (Object.Exists)
          {
            if (Object.VisibleOnScreen && Object.Enabled)
            {
              Log.Message("Object found & enabled on screen!");
      return Object; } } }
      Log.Error("Object not found in max number of iterations!"); return false; }

       

      • Kate's avatar
        Kate
        Contributor

        How do you guys handle errors that go to the Log?

        I would love to see my test green, but with checking while an element is visible or not visible I am getting this red error signs there, while overall test passes.

  • Vallalarasu_P's avatar
    Vallalarasu_P
    Frequent Contributor

    function waitWhile(condition, msg, timeout)
    dim t
    t = 0
    do While eval(condition) and t <= timeout
    delaytext = t & ” of ” & timeout & ” seconds passed waiting for ” & msg
    delay 1000, delaytext
    t = t + 1
    loop
    if t <= timeout then
    waitWhile = true
    else
    waitWhile = false
    log.event “Timeout expired waiting for ” & msg
    end if
    end function

    An example call to this would look like:

    call waitWhile(“aliases.pageObj.find(“”name””, “”elementname””, 4, true).exists”, “element to appear”, 30)

     

    Regards

    Valla

    https://vallatestcomplete.wordpress.com/