Handling Browser Differences

Applies to TestComplete 15.47, last modified on January 20, 2023

This topic describes typical issues that are caused by browser differences and tells how to resolve them:

Tip: To handle some of the described issues, you may need to determine the browser in which the test is being executed. See the Checking the Current Browser topic to learn how to do this.

Browser GUI Elements

Only the Web page access API is cross-browser; the browser's GUI object model is not. Browser GUI elements are different for each browser – menus, Option dialogs, Home/Back buttons, informative and warning pop-ups and so on. Actions over the browser’s GUI elements are browser-specific.

Browser Messages and Dialogs

TestComplete provides special test objects (Alert, Confirm, Prompt and Login) for automating some of the most frequently used browser and JavaScript dialogs. Actions over these test objects can be performed in any web browser. (See Handle JavaScript Popups and Browser Dialogs.) However, when a pop-up window or dialog cannot be recognized as one of these test objects, the corresponding window should be handled in a browser-specific manner.

For instance, when opening pages from local disks, Internet Explorer may ask you whether you want to allow active content on these pages. The other browsers do not display any warnings in the same case. Therefore, to make a test compatible with any browser, you should handle notifications in Internet Explorer:

Handling browser-specific windows.

JavaScript, JScript

...
  browser = Browsers.Item(i);
  browser.Run("file:///C:/Work//MyPage.htm");
   if (browser.Family == Browsers.btIExplorer) AllowActiveContent();
...

Python

...
  browser = Browsers.Item[i];
  browser.Run("file:///C:/Work//MyPage.htm");
  if (browser.Family == Browsers.btIExplorer):
    AllowActiveContent();
...

VBScript

...
   Set browser = Browsers.Item(i)
   browser.Run("file:///C:/Work//MyPage.htm")
   If (browser.Family = Browsers.btIExplorer) Then 
      AllowActiveContent()
   End If
...

DelphiScript

...
   browser := Browsers.Item(i);
   browser.Run('file:///C:/Work//MyPage.htm');
   if (browser.Family = Browsers.btIExplorer) then AllowActiveContent();
...

C++Script, C#Script

...
   browser = Browsers["Item"](i);
   browser["Run"]("file:///C:/Work//MyPage.htm");
   if (browser["Family"] == Browsers["btIExplorer"]) AllowActiveContent();
...

Edge-specific note: In all the supported browsers, except for Edge, the Window object that correspond to standard dialogs like Open File, Select Folder and others belong to the browser’s main process. In the Edge browser, the Window objects that represent these dialogs belong to a separate helper process named PickerHost. Therefore, to make a test compatible with any browser, you should handle the standard dialogs invoked from Edge:

Handling Open dialog under Edge browser.

JavaScript, JScript

...
   if (Browsers.CurrentBrowser.Family == Browsers.btEdge)
      var OpenDlg = Sys.Process("PickerHost").Window("#32770", "Open", 1);
   else
      var OpenDlg = Sys.Browser().Window("#32770", "Open", 1);
...

Python

...
  if (Browsers.CurrentBrowser.Family == Browsers.btEdge):
    OpenDlg = Sys.Process("PickerHost").Window("#32770", "Open", 1);
  else:
    OpenDlg = Sys.Browser().Window("#32770", "Open", 1);
...

VBScript

...
   If (Browsers.CurrentBrowser.Family = Browsers.btEdge) Then 
      Set OpenDlg = Sys.Process("PickerHost").Window("#32770", "Open", 1)
   Else
      Set OpenDlg = Sys.Browser().Window("#32770", "Open", 1)
   End If
...

DelphiScript

...
   if (Browsers.CurrentBrowser.Family = Browsers.btEdge) then
      OpenDlg := Sys.Process('PickerHost').Window('#32770', 'Open', 1);
   else
      OpenDlg := Sys.Browser().Window('#32770', 'Open', 1);
...

C++Script, C#Script

...
   if (Browsers["CurrentBrowser"]["Family"] == Browsers["btEdge"])
      var OpenDlg = Sys["Process"]("PickerHost")["Window"]("#32770", "Open", 1);
   else
      var OpenDlg = Sys["Browser"]()["Window"]("#32770", "Open", 1);
...

There can be several PickerHost processes in the system. In this case, you should use indexes to specify the process to which the needed dialog belongs:

JavaScript, JScript

Sys.Process("PickerHost", 2).Window("#32770", "Open", 1)

Python

Sys.Process("PickerHost", 2).Window("#32770", "Open", 1)

VBScript

Sys.Process("PickerHost", 2).Window("#32770", "Open", 1)

DelphiScript

Sys.Process('PickerHost', 2).Window('#32770', 'Open', 1)

C++Script, C#Script

Sys["Process"]("PickerHost", 2)["Window"]("#32770", "Open", 1)

Non-Matching Sets of DOM Methods and Properties

The layout engines (Trident, EdgeHTML, Blink, Gecko) used in web browsers to render web pages provide slightly dissimilar sets of methods and properties of web elements. The elements displayed in one of the layout engines do not always have the same set of methods and properties in other layout engines. Some members may have the same name and functionality, some members may have a similar functionality but different names, the other may have no analogs at all.

A typical example of non-matching properties is properties that provide access to a DOM document and to an element's text content. Any browser has these properties, however, their names do not coincide. To improve cross-browser compatibility, TestComplete adds special analogs:

  • To access the DOM document object of a web page: Page.contentDocument syntax for Chrome, Edge, Firefox, and Internet Explorer 11. You can also use the common Page.contentDocument syntax for all supported browsers. For more information, see Accessing DOM document Object.

  • To get the textual content of a web page object and its child objects in Firefox and Chrome, the textContent property is used, whereas to get the same data in Internet Explorer or Edge you should use the innerText property. TestComplete introduces an analogous property, contentText, which is available in all browsers.

The above-mentioned properties are most frequently used. To deal with other non-matching properties, you should first check whether a property is available or not.

Verifying if the browser or page element supports certain method or property

Since the set of methods and properties provided by different browsers may vary (see above), you should check whether the desired member is available in the current browser before using this method or property. To perform such verification, you can use the aqObject.IsSupported method.

The following code gets the window object associated with the document. In Internet Explorer 11, as well as in Chrome, Edge, and Firefox, the window object is returned by the document.defaultView property.

JavaScript, JScript

function GetDocWindow()
{
  var document, window;

  document = Aliases.browser.myTestedPage.contentDocument;
  // Check if the document.parentWindow property is available
  if (aqObject.IsSupported(document, "parentWindow"))
    window = document.parentWindow
  // Check if the document.defaultView property is available
  else if (aqObject.IsSupported(document, "defaultView"))
    window = document.defaultView
  else
    Log.Error("Unknown browser that doesn't support document.defaultView or document.parentWindow.");
}

Python

def GetDocWindow():
  document = Aliases.browser.myTestedPage.contentDocument;
  # Check if the document.parentWindow property is available
  if (aqObject.IsSupported(document, "parentWindow")):
    window = document.parentWindow;
  # Check if the document.defaultView property is available 
  else:
    if (aqObject.IsSupported(document, "defaultView")):
      window = document.defaultView;
    else:
      Log.Error("Unknown browser that doesn't support document.defaultView or document.parentWindow.");

VBScript

Sub GetDocWindow
  Dim document, window

  Set document = Aliases.browser.myTestedPage.contentDocument
  ' Check if the document.parentWindow property is available
  If (aqObject.IsSupported(document, "parentWindow")) Then
      Set window = document.parentWindow
  ' Check if the document.defaultView property is available
  Else If (aqObject.IsSupported(document, "defaultView")) Then
      Set window = document.defaultView
    Else
      Log.Error("Unknown browser that doesn't support document.defaultView or document.parentWindow.")
    End If
  End If
End Sub

DelphiScript

procedure GetDocWindow;
  var document, window: OleVariant;
begin
  document := Aliases.browser.myTestedPage.contentDocument;
  // Check if the document.parentWindow property is available
  if (aqObject.IsSupported(document, 'parentWindow')) then
    window := document.parentWindow
  // Check if the document.defaultView property is available
  else if (aqObject.IsSupported(document, 'defaultView')) then
    window := document.defaultView
  else
    Log.Error('Unknown browser that doesn''t support document.defaultView or document.parentWindow.');
end;

C++Script, C#Script

function GetDocWindow()
{
  var document, window;

  document = Aliases["browser"]["myTestedPage"]["contentDocument"];
  // Check if the document.parentWindow property is available
  if (aqObject["IsSupported"](document, "parentWindow"))
    window = document.parentWindow
  // Check if the document.defaultView property is available
  else if (aqObject["IsSupported"](document, "defaultView"))
    window = document.defaultView
  else
    Log["Error"]("Unknown browser that doesn't support document.defaultView or document.parentWindow.");
}

Attribute Values

Different browsers can report CSS style property values in different formats. For example, Internet Explorer can report colors as #ff0000 whereas Firefox and Chrome report them as rgb(255, 0, 0). You should take this into account when creating your tests.

For instance, when verifying element colors, you may check values in any notation, or convert one notation to another:

JavaScript, JScript

function CheckHeaderColor()
{
 ...
 var strColor = getStyle(header, "backgroundColor");
 
  //Compare the obtained color with two possible notations of the expected color
  if ((strColor=="rgb(255, 0, 0)") || (strColor=="#ff0000"))
    Log.Message("The header is as Red, as expected")
  else
    Log.Warning("The header is in another color.")
  ...
}

function CheckHeaderColor2()
{
  ...
 var strColor = getStyle(header, "backgroundColor");
  
  //Convert color notation for Internet Explorer
  if (Browsers.CurrentBrowser.Family==btIExplorer)
      strColor = html2rgb(strColor)
  //Compare the obtained color with the expected color
  if (strColor=="rgb(255, 0, 0)")
    Log.Message("The header is as Red, as expected")
  else
    Log.Warning("The header is in another color.")
    
  ...
}

Python

def CheckHeaderColor():
 # ...
 strColor = getStyle(header, "backgroundColor");
 
 # Compare the obtained color with two possible notations of the expected color 
 if ((strColor=="rgb(255, 0, 0)") or (strColor=="#ff0000")):
  Log.Message("The header is as Red, as expected");
 else:
  Log.Warning("The header is in another color."); 
 # ...

def CheckHeaderColor2():
  # ...
  strColor = getStyle(header, "backgroundColor");
  
  # Convert color notation for Internet Explorer and Opera 
  if (Browsers.CurrentBrowser.Family==btIExplorer): 
    strColor = html2rgb(strColor);
    # Compare the obtained color with the expected color 
  if (strColor=="rgb(255, 0, 0)"):
    Log.Message("The header is as Red, as expected");
  else:
    Log.Warning("The header is in another color.");
    
  # ...

VBScript

Sub CheckHeaderColor

  ...
  strColor = getStyle(header, "backgroundColor")
 
  'Compare the obtained color with two possible notations of the expected color
  If ((strColor="rgb(255, 0, 0)") Or (strColor="#ff0000")) Then
    Log.Message("The header is as Red, as expected")
  Else
    Log.Warning("The header is in another color.")
  End If
  ...
End Sub

Sub CheckHeaderColor2

  ...
  strColor = getStyle(header, "backgroundColor")
  
  'Convert color notation for Internet Explorer
  If ( Browsers.CurrentBrowser.Family=btIExplorer) Then
    strColor = html2rgb(strColor)
  End If
  
  'Compare the obtained color with the expected color
  If (strColor="rgb(255, 0, 0)") Then
    Log.Message("The header is as Red, as expected")
  Else
    Log.Warning("The header is in another color.")
  End If
  
  ...
End Sub

DelphiScript

procedure CheckHeaderColor;
begin
  ...
  strColor := getStyle(header, 'backgroundColor');
 
  //Compare the obtained color with two possible notations of the expected color
  if ((strColor='rgb(255, 0, 0)') or (strColor='#ff0000')) then
    Log.Message('The header is as Red, as expected')
  else
    Log.Warning('The header is in another color.')
  ...
end;

procedure CheckHeaderColor2;
begin
  ...
  strColor := getStyle(header, 'backgroundColor');
  
  //Convert color notation for Internet Explorer
  if (Browsers.CurrentBrowser.Family=btIExplorer) then 
      strColor := html2rgb(strColor);
 
  //Compare the obtained color with the expected color
  if (strColor='rgb(255, 0, 0)') then
    Log.Message('The header is as Red, as expected')
  else
    Log.Warning('The header is in another color.')
  ...
end;

C++Script, C#Script

function CheckHeaderColor()
{
  ...
 var strColor = getStyle(header, "backgroundColor");
 
  //Compare the obtained color with two possible notations of the expected color
  if ((strColor=="rgb(255, 0, 0)") || (strColor=="#ff0000"))
    Log["Message"]("The header is as Red, as expected")
  else
    Log["Warning"]("The header is in another color.")
  ...
}

function CheckHeaderColor2()
{
  ...
 var strColor = getStyle(header, "backgroundColor");
  
  //Convert color notation for Internet Explorer
  if (Browsers["CurrentBrowser"].Family==btIExplorer)
      strColor = html2rgb(strColor)
  //Compare the obtained color with the expected color
  if (strColor=="rgb(255, 0, 0)")
    Log["Message"]("The header is as Red, as expected")
  else
    Log["Warning"]("The header is in another color.")
    
  ...
}

See Also

About Cross-Browser Testing in TestComplete
Creating Cross Browser Tests
Running Tests in Multiple Browsers

Highlight search results