Applies to TestComplete 14.20, last modified on September 11, 2019

Before publishing your web site, you may need to validate the markup of its pages, validate CSS and check the site for broken links. Furthermore, you may need to do it every time the site contents are updated. To perform these tasks, you can use various third-party tools, for example, the tools mentioned in the “Website Checklist” article (http://www.xs4all.nl/~sbpoley/webmatters/checklist.html):

The W3C Markup Validation Service and WDG HTML Validator are used to validate HTML code. The W3C CSS Validation Service is used to validate the CSS and Link Valet is used to check for broken links.

All of these tools are similar:

  • You open a web page corresponding to the desired tool.
  • On the page, specify the web site to be checked and initiate the process.
  • After the check is over, you can save the results to a file and explore them to determine whether the check was successful.

You can easily check your web site for errors using the above-mentioned tools once or twice, but if you need to check your site regularly, it is better to automate this process. With TestComplete, you can create a script routine or a keyword test for checking and validating a web site and run it upon every change made to the site.

The general idea is:

  • Launch one of the supported browsers and open the validator page.

  • Specify the address of the page to be tested into the edit box displayed on the validator page.

  • Specify validator settings by simulating user actions over the corresponding page controls.

  • Start checking by clicking the corresponding button.

  • Wait until the web browser displays the check results.

  • Save the result page.

After performing these actions, you can open the result file and analyze it.

To improve re-usability and minimize repeated actions, we can divide the entire test onto several routines.

  • ValidateHTML_W3CMarkUpValidator - validates the web page markup using the W3C Markup Validation Service.

  • ValidateHTML_WDGValidator - validates the markup using the WDG HTML Validator.

  • ValidateCSS_W3C_CSS - validates CSS using the W3C CSS Validation Service.

  • ValidateHTML_LinkValet - checks the web page for broken links using Link Valet.

  • SaveResultPage - saves the page containing the checked results to a file.

  • Main - performs initialization actions and calls other routines.

Validating Web Pages Using Script

JavaScript, JScript

// Specifies the level of child objects where the desired objects will be searched for
var depth = 10;

function Main()
{
  if (Options.Web.TreeModel != "Tree")
  {
    Log.Warning("This example requires the Tree web model. Changed model to Tree.");
    Options.Web.TreeModel = "Tree";
  }

  // Creates a folder where the results will be stored
  resultsFolder = "C:\\" + aqConvert.DateTimeToFormatStr(aqDateTime.Now(), "%m_%d_%y_%H_%M") + "\\";
  aqFileSystem.CreateFolder(resultsFolder);

  Browsers.Item(btIExplorer).Run("about:blank");
  var browser = Sys.Browser("*");

  var URL = "http://www.microsoft.com/";

  // Calls validation procedures
  ValidateHTML_W3CMarkUpValidator(browser, URL, resultsFolder + "Validate_Microsoft_W3CMarkUp.html");
  ValidateHTML_WDGValidator(browser, URL, resultsFolder + "Validate_Microsoft_WDG.html");
  ValidateCSS_W3C_CSS(browser, URL, resultsFolder + "Validate_Microsoft_W3C_CSS.html",
                       "CSS level 1", "screen", "Most important");
  ValidateHTML_LinkValet(browser, URL, "2003-01-01", true, 1, resultsFolder + "Validate_Microsoft_LinkValet.html");

}


// Checking for broken links using Link Valet
function ValidateHTML_LinkValet (browserProcess, address,
modifiedDate,
fullReport, // True means Full Report, False means Summary Report
recursionDepth, // 0, 1 or 2
resultFile)
{

  var page = browserProcess.ToUrl("http://valet.webthing.com/link/");
  // Locates the "Address" field and inputs the URL to be checked
  page.FindChild("ObjectIdentifier", "url", depth).value = address;

  // Locates the "Highlight links modified since" field and sets the date
  page.FindChild("ObjectIdentifier", "date", depth).value = modifiedDate;

  // Selects either the Full Report, or Summary Report option

  if (fullReport)
    page.FindChild("ObjectIdentifier", "type", depth).Click();
  else
    page.FindChild("ObjectIdentifier", "type_2", depth).Click();


  // Specifies the Recursion depth
  switch (recursionDepth)
  {
    case 0 : page.FindChild("ObjectIdentifier", "depth", depth).Click(); break;
    case 1 : page.FindChild("ObjectIdentifier", "depth_2", depth).Click(); break;
    case 2 : page.FindChild("ObjectIdentifier", "depth_3", depth).Click(); break;
  }

  // Locates the "OK" button and clicks it
  page.FindChild("ObjectIdentifier", "OK", depth).Click();

  // Waits until downloading completes
  page.Wait();

  // Saves the result
  SaveResultPage(browserProcess, resultFile);
  Log.Message("Link results of the Link Valet have been saved to the following file: "
              + resultFile);

}


// Validating CSS using W3C CSS Validation Service
function ValidateCSS_W3C_CSS (browserProcess, address, resultFile, profile, medium, warning)
{

  page = browserProcess.ToUrl("http://jigsaw.w3.org/css-validator/#validate_by_uri");

  // Locates the "Validate by URI" tab
  tab = page.FindChild("idStr", "validate-by-uri", depth);

  // Locates the "Address" field and inputs the URL to be checked
  tab.FindChild("idStr", "uri", depth).value = address;
  // Locates the "More Options" panel

  extraOptions = tab.FindChild("idStr", "extra_opt_uri", depth);

  if (extraOptions.Exists)
  {
    // Expands the "More Options" panel
    extraOptions.FindChild("ContentText", "More Options", depth).Click();

    // Locates the "Profile", "Medium" and "Warnings" combo boxes
    extraOptions.FindChild("idStr", "profile_uri", depth).ClickItem(profile);
    extraOptions.FindChild("idStr", "warning_uri", depth).ClickItem(warning);
    extraOptions.FindChild("idStr", "medium_uri", depth).ClickItem(medium);
  }

  // Locates the "Check" button and clicks it
  tab.FindChild("className", "submit", depth).Click();

  // Waits until downloading completes
  page.Wait();

  // Saves the results
  SaveResultPage(browserProcess, resultFile);
  Log.Message("CSS results of the W3C CSS Validation Service have been saved to the following file: "

              + resultFile);

}


// Validating HTML markup using WDG HTML Validator
function ValidateHTML_WDGValidator (browserProcess, address, resultFile)
{

  var page = browserProcess.ToUrl("http://www.htmlhelp.com/tools/validator/");

  // Locates the "Address" field and inputs the URL to be checked
  page.FindChild("ObjectIdentifier", "url", depth).value = address;

  // Locates the "Validate it" button and clicks it
  page.FindChild("ObjectIdentifier", "Validate*", depth).Click();

  // Waits until downloading completes
  page.Wait();

  // Saves the results
  SaveResultPage(browserProcess, resultFile);
  Log.Message("HTML results of the WDG HTML Validator have been saved to the following file: "
              + resultFile);
}


// Validating HTML markup using W3C Markup Validation Service
function ValidateHTML_W3CMarkUpValidator(browserProcess, address, resultFile)
{

  page = browserProcess.ToUrl("http://validator.w3.org/");
  // Locates the "Validate by URI" tab
  tab = page.FindChild("idStr", "validate-by-uri", depth);

  // Locates the "Address" field and inputs the URL to be checked
  tab.FindChild("idStr", "uri", 10).value = address;

  // Locates the "Check" button and clicks it
  tab.FindChild("className", "submit", depth).Click();

  // Waits until downloading completes
  page.Wait();

  // Saves the results
  SaveResultPage(browserProcess, resultFile);
  Log.Message("HTML results of the W3C Markup Validation Service have been saved to the following file: "
              + resultFile);

}


// Saves the web page to a file
function SaveResultPage(browserProcess, resultFile)
{

  // Calls the Save dialog by simulating pressing the Ctrl-S shortcut
  browserProcess.Page("*").Keys("^s");
  saveDlg = browserProcess.Window("#32770", "Save*");

  // Saves the result
  saveDlg.SaveFile(resultFile);

  if (browserProcess.ObjectIdentifier == "iexplore")
  {
    while (browserProcess.Page("*").WaitAlert(3000).Exists)
    {
      Delay(500);
    }
  }

}

Python

# Specifies the level of child objects where the desired objects will be searched for
depth = 10;

def Main():
  if (Options.Web.TreeModel != "Tree"):
    Log.Warning("This example requires the Tree web model. Changed model to Tree.");
    Options.Web.TreeModel = "Tree";

  # Creates a folder where the results will be stored
  resultsFolder = "C:\\" + aqConvert.DateTimeToFormatStr(aqDateTime.Now(), "%m_%d_%y_%H_%M") + "\\";
  aqFileSystem.CreateFolder(resultsFolder);

  Browsers.Item[btIExplorer].Run("about:blank");
  browser = Sys.Browser("*");

  URL = "http://www.microsoft.com/";

  # Calls validation procedures
  ValidateHTML_W3CMarkUpValidator(browser, URL, resultsFolder + "Validate_Microsoft_W3CMarkUp.html");
  ValidateHTML_WDGValidator(browser, URL, resultsFolder + "Validate_Microsoft_WDG.html");
  ValidateCSS_W3C_CSS(browser, URL, resultsFolder + "Validate_Microsoft_W3C_CSS.html",
                       "CSS level 1", "screen", "Most important");
  ValidateHTML_LinkValet(browser, URL, "2003-01-01", True, 1, resultsFolder + "Validate_Microsoft_LinkValet.html");


# Checking for broken links using Link Valet
def ValidateHTML_LinkValet (browserProcess, address,
modifiedDate,
fullReport, # True means Full Report, False means Summary Report
recursionDepth, # 0, 1 or 2
resultFile):
  page = browserProcess.ToUrl("http://valet.webthing.com/link/");
  # Locates the "Address" field and inputs the URL to be checked
  page.FindChild("ObjectIdentifier", "url", depth).value = address;

  # Locates the "Highlight links modified since" field and sets the date
  page.FindChild("ObjectIdentifier", "date", depth).value = modifiedDate;

  # Selects either the Full Report, or Summary Report option

  if (fullReport):
    page.FindChild("ObjectIdentifier", "type", depth).Click();
  else:
    page.FindChild("ObjectIdentifier", "type_2", depth).Click();


  # Specifies the Recursion depth
  if (recursionDepth == 0):
    page.FindChild("ObjectIdentifier", "depth", depth).Click();
  elif (recursionDepth == 1):
    page.FindChild("ObjectIdentifier", "depth_2", depth).Click();
  elif (recursionDepth == 2):
    page.FindChild("ObjectIdentifier", "depth_3", depth).Click();

  # Locates the "OK" button and clicks it
  page.FindChild("ObjectIdentifier", "OK", depth).Click();

  # Waits until downloading completes
  page.Wait();

  # Saves the result
  SaveResultPage(browserProcess, resultFile);
  Log.Message("Link results of the Link Valet have been saved to the following file: " + \
              resultFile);


# Validating CSS using W3C CSS Validation Service
def ValidateCSS_W3C_CSS (browserProcess, address, resultFile, profile, medium, warning):
  page = browserProcess.ToUrl("http://jigsaw.w3.org/css-validator/#validate_by_uri");

  # Locates the "Validate by URI" tab
  tab = page.FindChild("idStr", "validate-by-uri", depth);

  # Locates the "Address" field and inputs the URL to be checked
  tab.FindChild("idStr", "uri", depth).value = address;
  # Locates the "More Options" panel

  extraOptions = tab.FindChild("idStr", "extra_opt_uri", depth);

  if (extraOptions.Exists):
    # Expands the "More Options" panel
    extraOptions.FindChild("ContentText", "More Options", depth).Click();

    # Locates the "Profile", "Medium" and "Warnings" combo boxes
    extraOptions.FindChild("idStr", "profile_uri", depth).ClickItem(profile);
    extraOptions.FindChild("idStr", "warning_uri", depth).ClickItem(warning);
    extraOptions.FindChild("idStr", "medium_uri", depth).ClickItem(medium);

  # Locates the "Check" button and clicks it
  tab.FindChild("className", "submit", depth).Click();

  # Waits until downloading completes
  page.Wait();

  # Saves the results
  SaveResultPage(browserProcess, resultFile);
  Log.Message("CSS results of the W3C CSS Validation Service have been saved to the following file: " + \
                resultFile);

# Validating HTML markup using WDG HTML Validator
def ValidateHTML_WDGValidator (browserProcess, address, resultFile):
  page = browserProcess.ToUrl("http://www.htmlhelp.com/tools/validator/");

  # Locates the "Address" field and inputs the URL to be checked
  page.FindChild("ObjectIdentifier", "url", depth).value = address; 

  # Locates the "Validate it" button and clicks it
  page.FindChild("ObjectIdentifier", "Validate*", depth).Click();

  # Waits until downloading completes
  page.Wait();

  # Saves the results
  SaveResultPage(browserProcess, resultFile);
  Log.Message("HTML results of the WDG HTML Validator have been saved to the following file: " + \
              resultFile);

# Validating HTML markup using W3C Markup Validation Service
def ValidateHTML_W3CMarkUpValidator(browserProcess, address, resultFile):
  page = browserProcess.ToUrl("http://validator.w3.org/");
  # Locates the "Validate by URI" tab
  tab = page.FindChild("idStr", "validate-by-uri", depth);

  # Locates the "Address" field and inputs the URL to be checked
  tab.FindChild("idStr", "uri", 10).value = address;

  # Locates the "Check" button and clicks it
  tab.FindChild("className", "submit", depth).Click();

  # Waits until downloading completes
  page.Wait();

  # Saves the results
  SaveResultPage(browserProcess, resultFile);
  Log.Message("HTML results of the W3C Markup Validation Service have been saved to the following file: " + \
              resultFile);


# Saves the web page to a file
def SaveResultPage(browserProcess, resultFile):

  # Calls the Save dialog by simulating pressing the Ctrl-S shortcut
  browserProcess.Page("*").Keys("^s"); 
  saveDlg = browserProcess.Window("#32770", "Save*");

  # Saves the result
  saveDlg.SaveFile(resultFile);

  if (browserProcess.ObjectIdentifier == "iexplore"):
    while (browserProcess.Page("*").WaitAlert(3000).Exists):
      Delay(500);

VBScript

' Specifies the level of child objects where the desired objects will be searched for
depth = 10

Sub Main()

  Dim browser, resultsFolder, URL

  If Options.Web.TreeModel <> "Tree" Then
    Log.Warning("This example requires the Tree web model. Changed model to Tree.")
    Options.Web.TreeModel = "Tree"
  End If

  ' Creates a folder where the results will be stored
  resultsFolder = "C:\" & aqConvert.DateTimeToFormatStr(aqDateTime.Now(), "%m_%d_%y_%H_%M") & "\"
  aqFileSystem.CreateFolder(resultsFolder)

  Browsers.Item(btIExplorer).Run "about:blank"
  Set browser = Sys.Browser("*")

  URL = "http://www.microsoft.com/"

  ' Calls validation procedures
  Call ValidateHTML_W3CMarkUpValidator(browser, URL, resultsFolder + "Validate_Microsoft_W3CMarkUp.html")
  Call ValidateHTML_WDGValidator(browser, URL, resultsFolder + "Validate_Microsoft_WDG.html")
  Call ValidateCSS_W3C_CSS(browser, URL, resultsFolder + "Validate_Microsoft_W3C_CSS.html", _
                           "CSS level 1", "screen", "Most important")
  Call ValidateHTML_LinkValet(browser, URL, "2003-01-01", true, 1, resultsFolder + "Validate_Microsoft_LinkValet.html")

End Sub


' Checking for broken links using Link Valet
' FullReport is True for a full report, False for a summary report
' RecursionDepth is either 0, 1 or 2

Sub ValidateHTML_LinkValet (browserProcess, address, modifiedDate, fullReport, _
                            recursionDepth,resultFile)

  Dim page
  Set page = browserProcess.ToUrl("http://valet.webthing.com/link/")

  ' Locates the "Address" field and inputs the URL to be checked
  page.FindChild("ObjectIdentifier", "url", depth).value = address

  ' Locates the "Highlight links modified since" field and sets the date
  page.FindChild("ObjectIdentifier", "date", depth).value = modifiedDate

  ' Selects either the Full Report, or Summary Report option
  If fullReport Then
    page.FindChild("ObjectIdentifier", "type", depth).Click
  Else
    page.FindChild("ObjectIdentifier", "type_2", depth).Click
  End If
  ' Specifies the Recursion depth

  Select Case recursionDepth
    Case 0
      page.FindChild("ObjectIdentifier", "depth", depth).Click
    Case 1
      page.FindChild("ObjectIdentifier", "depth_2", depth).Click
    Case 2
      page.FindChild("ObjectIdentifier", "depth_3", depth).Click
  End Select

  ' Locates the "OK" button and clicks it
  page.FindChild("ObjectIdentifier", "OK", depth).Click

  ' Waits until downloading completes
  page.Wait

  ' Saves the result
  Call SaveResultPage(browserProcess, resultFile)
  Log.Message("Link results of the Link Valet have been saved to the following file: "_
              & resultFile)

End Sub


' Validating CSS using W3C CSS Validation Service
Sub ValidateCSS_W3C_CSS (browserProcess, address, resultFile, profile, medium, warning)

  Dim page, tab, extraOptions
  Set page = browserProcess.ToUrl("http://jigsaw.w3.org/css-validator/#validate_by_uri")

  ' Locates the "Validate by URI" tab
  Set tab = page.FindChild("idStr", "validate-by-uri", depth)

  ' Locates the "Address" field and inputs the URL to be checked
  tab.FindChild("idStr", "uri", depth).value = address

  ' Locates the "More Options" panel
  Set extraOptions = tab.FindChild("idStr", "extra_opt_uri", depth)

  If extraOptions.Exists Then
    ' Expands the "More Options" panel
    extraOptions.FindChild("ContentText", "More Options", depth).Click

    ' Locates the "Profile", "Medium" and "Warnings" combo boxes
    extraOptions.FindChild("idStr", "profile_uri", depth).ClickItem(profile)
    extraOptions.FindChild("idStr", "warning_uri", depth).ClickItem(warning)
    extraOptions.FindChild("idStr", "medium_uri", depth).ClickItem(medium)
  End If

  ' Locates the "Check" button and clicks it
  tab.FindChild("className", "submit", depth).Click

  ' Waits until downloading completes
  page.Wait

  ' Saves the results
  Call SaveResultPage(browserProcess, resultFile)
  Log.Message("CSS results of the W3C CSS Validation Service have been saved to the following file: " _
              & resultFile)

End Sub


' Validating HTML markup using WDG HTML Validator
Sub ValidateHTML_WDGValidator (browserProcess, address, resultFile)

  Dim page
  Set page = browserProcess.ToUrl("http://www.htmlhelp.com/tools/validator/")

  ' Locates the "Address" field and inputs the URL to be checked
  page.FindChild("ObjectIdentifier", "url", depth).value = address

  ' Locates the "Validate it" button and clicks it
  page.FindChild("ObjectIdentifier", "Validate*", depth).Click

  ' Waits until downloading completes
  page.Wait

  ' Saves the results
  Call SaveResultPage(browserProcess, resultFile)
  Log.Message("HTML results of the WDG HTML Validator have been saved to the following file: "_
              & resultFile)

End Sub


' Validating HTML markup using W3C Markup Validation Service
Sub ValidateHTML_W3CMarkUpValidator(browserProcess, address, resultFile)

  Dim page, tab
  Set page = browserProcess.ToUrl("http://validator.w3.org/")

  ' Locates the "Validate by URI" tab
  Set tab = page.FindChild("idStr", "validate-by-uri", depth)

  ' Locates the "Address" field and inputs the URL to be checked
  tab.FindChild("idStr", "uri", 10).value = address

  ' Locates the "Check" button and clicks it
  tab.FindChild("className", "submit", depth).Click

  ' Waits until downloading completes
  page.Wait

  ' Saves the results
  Call SaveResultPage(browserProcess, resultFile)
  Log.Message("HTML results of the W3C Markup Validation Service have been saved to the following file: "_
              & resultFile)

End Sub


' Saves a web page to a file
Sub SaveResultPage(browserProcess, resultFile)

  Dim browserWindow, saveDlg
  ' Calls the Save dialog by simulating pressing the Ctrl-S shortcut
  browserProcess.Page("*").Keys("^s")

  Set saveDlg = browserProcess.Window("#32770", "Save*")

  ' Saves the result
  saveDlg.SaveFile(resultFile)

  If browserProcess.ObjectIdentifier = "iexplore" Then
    While browserProcess.Page("*").WaitAlert(3000).Exists
      Delay(500)
    Wend
  End if

End Sub

DelphiScript

// Forward declarations
procedure ValidateHTML_LinkValet (browserProcess, address, modifiedDate, fullReport, recursionDepth, resultFile); forward;
procedure ValidateCSS_W3C_CSS (browserProcess, address, resultFile, profile, medium, warning); forward;
procedure ValidateHTML_WDGValidator (browserProcess, address, resultFile); forward;
procedure ValidateHTML_W3CMarkUpValidator(browserProcess, address, resultFile); forward;
procedure SaveResultPage(browserProcess, resultFile); forward;

// Specifies the level of child objects where the desired objects will be searched for
const depth = 10;

procedure Main();
var browser, resultsFolder, URL;
var browser, resultsFolder, URL;
begin

  if Options.Web.TreeModel <> 'Tree' then
  begin
    Log.Warning('This example requires the Tree web model. Changed model to Tree.');

    Options.Web.TreeModel := 'Tree';
  end;

  // Creates a folder where the results will be stored
  resultsFolder := 'C:\' + aqConvert.DateTimeToFormatStr(aqDateTime.Now, '%m_%d_%y_%H_%M') + '\';
  aqFileSystem.CreateFolder(resultsFolder);

  Browsers.Item[btIExplorer].Run('about:blank');
  browser := Sys.Browser('*');

  URL := 'http://www.microsoft.com/';

  // Calls validation procedures
  ValidateHTML_W3CMarkUpValidator(browser, URL, resultsFolder + 'Validate_Microsoft_W3CMarkUp.html');
  ValidateHTML_WDGValidator(browser, URL, resultsFolder + 'Validate_Microsoft_WDG.html');
  ValidateCSS_W3C_CSS(browser, URL, resultsFolder + 'Validate_Microsoft_W3C_CSS.html',
                      'CSS level 1', 'screen', 'Most important');
  ValidateHTML_LinkValet(browser, URL, '2003-01-01', true, 1, resultsFolder + 'Validate_Microsoft_LinkValet.html');

end;


// Checks for broken links using Link Valet
procedure ValidateHTML_LinkValet (browserProcess, address,
modifiedDate,
fullReport, // True means Full Report, False means Summary Report
recursionDepth, // 0, 1 or 2
resultFile);

var page;
begin

  page := browserProcess.ToUrl('http://valet.webthing.com/link/');

  // Locates the "Address" field and inputs the URL to be checked
  page.FindChild('ObjectIdentifier', 'url', depth).value := address;

  // Locates the "Highlight links modified since" field and sets the date
  page.FindChild('ObjectIdentifier', 'date', depth).value := modifiedDate;

  // Selects either the Full Report, or Summary Report option
  if fullReport then
    page.FindChild('ObjectIdentifier', 'type', depth).Click
  else
    page.FindChild('ObjectIdentifier', 'type_2', depth).Click;

  // Specifies the Recursion depth

  case recursionDepth of
    0 : page.FindChild('ObjectIdentifier', 'depth', depth).Click;
    1 : page.FindChild('ObjectIdentifier', 'depth_2', depth).Click;
    2 : page.FindChild('ObjectIdentifier', 'depth_3', depth).Click;
  end;

  // Locates the "OK" button and clicks it
  page.FindChild('ObjectIdentifier', 'OK', depth).Click;

  // Waits until download completes
  page.Wait;

  // Saves the result
  SaveResultPage(browserProcess, resultFile);
  Log.Message('Link results of the Link Valet have been saved to the following file: '
              + resultFile);
end;


// Validating CSS using W3C CSS Validation Service
procedure ValidateCSS_W3C_CSS (browserProcess, address, resultFile, profile, medium, warning);
var page, tab, extraOptions;
begin

  page := browserProcess.ToUrl('http://jigsaw.w3.org/css-validator/#validate_by_uri');

  // Locates the "Validate by URI" tab
  tab := page.FindChild('idStr', 'validate-by-uri', depth);

  // Locates the "Address" field and inputs the URL to be checked
  tab.FindChild('idStr', 'uri', depth).value := address;

  // Locates the "More Options" panel
  extraOptions := tab.FindChild('idStr', 'extra_opt_uri', depth);

  if extraOptions.Exists then
  begin
    // Expands the "More Options" panel
    extraOptions.FindChild('ContentText', 'More Options', depth).Click;

    // Locates the "Profile", "Medium" and "Warnings" combo boxes
    extraOptions.FindChild('idStr', 'profile_uri', depth).ClickItem(profile);
    extraOptions.FindChild('idStr', 'warning_uri', depth).ClickItem(warning);
    extraOptions.FindChild('idStr', 'medium_uri', depth).ClickItem(medium);
  end;

  // Locates the "Check" button and clicks it
  tab.FindChild('className', 'submit', depth).Click();

  // Waits until downloading completes
  page.Wait;
  // Saves the results
  SaveResultPage(browserProcess, resultFile);
  Log.Message('CSS results of the W3C CSS Validation Service have been saved to the following file: '
              + resultFile);

end;

// Validating HTML markup using WDG HTML Validator
procedure ValidateHTML_WDGValidator (browserProcess, address, resultFile);
var page;
begin

  page := browserProcess.ToUrl('http://www.htmlhelp.com/tools/validator/');
  // Locates the "Address" field and inputs the URL to be checked
  page.FindChild('ObjectIdentifier', 'url', depth).value := address;

  // Locates the "Validate it" button and clicks it
  page.FindChild('ObjectIdentifier', 'Validate*', depth).Click;

  // Waits until downloading completes
  page.Wait;

  // Saves the results
  SaveResultPage(browserProcess, resultFile);
  Log.Message('HTML results of the WDG HTML Validator have been saved to the following file: '
              + resultFile);

end;

// Validating HTML markup using W3C Markup Validation Service
procedure ValidateHTML_W3CMarkUpValidator(browserProcess, address, resultFile);
var page, tab;
begin

  page := browserProcess.ToUrl('http://validator.w3.org/');

  // Locates the "Validate by URI" tab
  tab := page.FindChild('idStr', 'validate-by-uri', depth);

  // Locates the "Address" field and inputs the URL to be checked
  tab.FindChild('idStr', 'uri', 10).value := address;

  // Locates the "Check" button and clicks it
  tab.FindChild('className', 'submit', depth).Click;

  // Waits until downloading completes
  page.Wait;

  // Saves the results
  SaveResultPage(browserProcess, resultFile);
  Log.Message('HTML results of the W3C Markup Validation Service have been saved to the following file: '
              + resultFile);

end;


// Saves the web page to a file
procedure SaveResultPage(browserProcess, resultFile);
var browserWindow, saveDlg;
begin

  // Calls the Save dialog by simulating pressing the Ctrl-S shortcut
  browserProcess.Page('*').Keys('^s');

  saveDlg := browserProcess.Window('#32770', 'Save*');

  // Saves the result
  saveDlg.SaveFile(resultFile);

  if browserProcess.ObjectIdentifier = 'iexplore' then
  begin
    while (browserProcess.Page('*').WaitAlert(3000).Exists) do

    Delay(500);

  end;

end;

C++Script, C#Script

// Specifies the level of child objects where the desired objects will be searched for
var depth = 10;

function Main()
{
  if (Options["Web"]["TreeModel"] != "Tree")
  {
    Log["Warning"]("This example requires the Tree web model. Changed model to Tree.");
    Options["Web"]["TreeModel"] = "Tree";
  }

  // Creates a folder where the results will be stored
  resultsFolder = "C:\\" + aqConvert["DateTimeToFormatStr"](aqDateTime["Now"](), "%m_%d_%y_%H_%M") + "\\";
  aqFileSystem.CreateFolder(resultsFolder);

  Browsers["Item"](btIExplorer)["Run"]("about:blank");
  var browser = Sys["Browser"]("*");
  var URL = "http://www.microsoft.com/";

  // Calls validation procedures
  ValidateHTML_W3CMarkUpValidator(browser, URL, resultsFolder + "Validate_Microsoft_W3CMarkUp.html");
  ValidateHTML_WDGValidator(browser, URL, resultsFolder + "Validate_Microsoft_WDG.html");
  ValidateCSS_W3C_CSS(browser, URL, resultsFolder + "Validate_Microsoft_W3C_CSS.html",
                       "CSS level 1", "screen", "Most important");
  ValidateHTML_LinkValet(browser, URL, "2003-01-01", true, 1, resultsFolder + "Validate_Microsoft_LinkValet.html");

}


// Checks for broken links using Link Valet
function ValidateHTML_LinkValet (browserProcess, address,
modifiedDate,
fullReport, // True means Full Report, False means Summary Report
recursionDepth, // 0, 1 or 2
resultFile)
{

  var page = browserProcess["ToUrl"]("http://valet.webthing.com/link/");
  // Locates the "Address" field and inputs the URL to be checked
  page.FindChild("ObjectIdentifier", "url", depth)["value"] = address;

  // Locates the "Highlight links modified since" field and sets the date
  page.FindChild("ObjectIdentifier", "date", depth)["value"] = modifiedDate;

  // Selects either the Full Report, or Summary Report option

  if (fullReport)
    page["FindChild"]("ObjectIdentifier", "type", depth)["Click"]();
  else
    page["FindChild"]("ObjectIdentifier", "type_2", depth)["Click"]();


  // Specifies the Recursion depth
  switch (recursionDepth)
  {
    case 0 : page["FindChild"]("ObjectIdentifier", "depth", depth)["Click"](); break;
    case 1 : page["FindChild"]("ObjectIdentifier", "depth_2", depth)["Click"](); break;
    case 2 : page["FindChild"]("ObjectIdentifier", "depth_3", depth)["Click"](); break;
  }

  // Locates the "OK" button and clicks it
  page["FindChild"]("ObjectIdentifier", "OK", depth)["Click"]();

  // Waits until downloading completes
  page["Wait"]();

  // Saves the result
  SaveResultPage(browserProcess, resultFile);
  Log["Message"]("Link results of the Link Valet have been saved to the following file: "
              + resultFile);

}


// Validating CSS using W3C CSS Validation Service
function ValidateCSS_W3C_CSS (browserProcess, address, resultFile, profile, medium, warning)
{

  page = browserProcess["ToUrl"]("http://jigsaw.w3.org/css-validator/#validate_by_uri");

  // Locates the "Validate by URI" tab
  tab = page["FindChild"]("idStr", "validate-by-uri", depth);

  // Locates the "Address" field and inputs the URL to be checked
  tab["FindChild"]("idStr", "uri", depth).value = address;
  // Locates the "More Options" panel

  extraOptions = tab["FindChild"]("idStr", "extra_opt_uri", depth);

  if (extraOptions["Exists"])
  {
    // Expands the "More Options" panel
    extraOptions["FindChild"]("ContentText", "More Options", depth)["Click"]();

    // Locates the "Profile", "Medium" and "Warnings" combo boxes
    extraOptions["FindChild"]("idStr", "profile_uri", depth)["ClickItem"](profile);
    extraOptions["FindChild"]("idStr", "warning_uri", depth)["ClickItem"](warning);
    extraOptions["FindChild"]("idStr", "medium_uri", depth)["ClickItem"](medium);
  }

  // Locates the "Check" button and clicks it
  tab["FindChild"]("className", "submit", depth)["Click"]();

  // Waits until downloading completes
  page["Wait"]();

  // Saves the results
  SaveResultPage(browserProcess, resultFile);
  Log["Message"]("CSS results of the W3C CSS Validation Service have been saved to the following file: "

              + resultFile);

}


// Validating HTML markup using WDG HTML Validator
function ValidateHTML_WDGValidator (browserProcess, address, resultFile)
{

  var page = browserProcess["ToUrl"]("http://www.htmlhelp.com/tools/validator/");

  // Locates the "Address" field and inputs the URL to be checked
  page["FindChild"]("ObjectIdentifier", "url", depth)["value"] = address;

  // Locates the "Validate it" button and clicks it
  page["FindChild"]("ObjectIdentifier", "Validate*", depth)["Click"]();

  // Waits until downloading completes
  page["Wait"]();

  // Saves the results
  SaveResultPage(browserProcess, resultFile);
  Log["Message"]("HTML results of the WDG HTML Validator have been saved to the following file: "
              + resultFile);
}


// Validating HTML markup using W3C Markup Validation Service
function ValidateHTML_W3CMarkUpValidator(browserProcess, address, resultFile)
{

  page = browserProcess["ToUrl"]("http://validator.w3.org/");
  // Locates the "Validate by URI" tab
  tab = page["FindChild"]("idStr", "validate-by-uri", depth);

  // Locates the "Address" field and inputs the URL to be checked
  tab["FindChild"]("idStr", "uri", 10)["value"] = address;

  // Locates the "Check" button and clicks it
  tab["FindChild"]("className", "submit", depth)["Click"]();

  // Waits until downloading completes
  page["Wait"]();

  // Saves the results
  SaveResultPage(browserProcess, resultFile);
  Log["Message"]("HTML results of the W3C Markup Validation Service have been saved to the following file: "
              + resultFile);

}


// Saves the web page to a file
function SaveResultPage(browserProcess, resultFile)
{

  // Calls the Save dialog by simulating pressing the Ctrl-S shortcut
  browserProcess["Page"]("*")["Keys"]("^s");

  saveDlg = browserProcess["Window"]("#32770", "Save*");

  // Saves the result
  saveDlg["SaveFile"](resultFile);

  if (browserProcess["ObjectIdentifier"] == "iexplore")
  {
    while (browserProcess["Page"]("*")["WaitAlert"](3000)["Exists"])
    {
      Delay(500);
    }
  }

}

Validating Web Pages Using Keyword Tests

Creating the SaveResultPage Subprocedure

This subprocedure should save the currently open web page to the location specified in the input parameter.

To create the subprocedure, perform the following steps:

  • Open your web browser and navigate to any web page.

  • In TestComplete, right-click the KeywordTests node in the Project Explorer and choose Add | New Item from the context menu.

  • In the ensuing Create Project Item dialog, specify SaveResultPage as the test name and press OK.

    A new empty test will be opened in the Keyword Test editor.

  • Switch to the Parameters page and add a string parameter with the name ResultFile.

    This parameter specifies the local path of the saved web page.

  • Switch back to the Test Steps page.

  • Add the On-Screen Action operation. In the ensuing Operation Parameters wizard, specify operation parameters as follows:

    • Object name: Sys.Browser("*").BrowserWindow(0)

    • Method name: Keys.

    • Method’s Parameter: ^S.

    This operation simulates the Ctrl + S keystroke, which invokes the Save dialog in any browser.

  • Switch to the web browser and press Ctrl + S to invoke the Save dialog.

  • Add another On-Screen Action operation. It should relate to the Save dialog window. Select it with the target glyph. We're interested in the SaveFile method of this dialog. Specify the method’s FileName parameter to retrieve the destination file path from the test’s ResultFile parameter:

    • In the Operation Parameters dialog, select the FileName parameter and click the ellipsis button in the Value column.
    • In the ensuing Edit Parameter dialog, select Test Parameter in the Mode column, choose ResultFile from the Value drop-down list.
    • Press OK to close the Edit Parameter dialog. Press Finish to close the Operation Parameters dialog.
  • Add a Delay operation. Specify 3000 as the operation’s Delay Time parameter.

    This operation will delay the test execution for 3 seconds in order for the web browser to have enough time to save the web page.

Creating ValidateHTML_W3CMarkUpValidator subprocedure

This procedure will launch the web browser, navigate to the validator’s site, input the URL to be checked, wait for the validation results, call the SaveResultPage subprocedure to save them and close the browser afterwards. To address the elements of the web page this test uses the Tree model, if you use other web tree models, change the operations that interact with page’s controls.

To create the subprocedure, we will use the following technique: first, record most of the required actions and then modify the recorded test.

  • In TestComplete, select Test | Record | Record Keyword Test from the main menu.

    Test recording will start.

  • Launch the web browser and navigate to: http://validator.w3.org/.

  • Click within the Address field of the Markup Validation Service page and enter any URL in this field (say, www.microsoft.com).

  • Click the Check button of the web page.

  • Wait for the page to reload and display the verification results.

  • Close the browser.

  • Press Stop on the Recording toolbar.

  • Rename the recorded test to ValidateHTML_W3CMarkUpValidator.

As you may notice, we have entered the validated URL manually and have not saved the validation results. Now we need to parameterize the recorded test in order to call it from other tests.

  • Switch to the Parameters page and add two string parameters: CheckedURL and ResultFile.

    The first parameter specifies the URL of the page to be validated. The second parameter - the path where the validation results are saved. The value of the second parameter will be passed to the SaveResultPage subprocedure.

  • Switch back to the Test Steps page.

  • Substitute the arbitrary URL name we have entered (www.microsoft.com) with the CheckedURL parameter:

    • Locate the operation that corresponds to the URL input. This is the operation that calls the SetText action.

    • The Value column for this operation contains the entered URL. Click the ellipsis button next to this value. This will invoke the Operation Parameters dialog.

    • In the dialog, select the Text parameter and click the ellipsis button in the Value column. In the ensuing Edit Parameter dialog, select Test Parameter in the Mode column and choose CheckedURL from the Value drop-down list.
    • Press OK to close the Edit Parameter dialog. Press OK to close the Operation Parameters dialog.

  • Insert the Run Keyword Test operation between the operations that wait for the results and close the browser. Specify the operation parameters to call the SaveResultPage subprocedure with the ResultFile test parameter.

The rest of the subprocedures that deal with validation services are created in a similar way.

Creating Main test

This test should set the required web tree model and call the sub-tests that works with validation services. To create the Main test perform the following actions:

  • Create a new keyword test and name it Main.

  • Add the If ... Then operation to your test to check for the current web tree model. Specify the following condition: Options.Web.TreeModel not equal to "Tree".

  • Add the Run Code Snippet operation as the child of the If ... Then operation. Specify the following code fragment to be executed: Options.Web.TreeModel = "Tree".

    The operation will set the Tree model if some other web tree model is enabled.

  • Add the Run Keyword Test operation and call the ValidateHTML_W3CMarkUpValidator subprocedure. Pass the URL you want to check (say, www.google.com) as the first parameter, and the full path where to store the verification result as the second parameter.

  • Add three more Run Keyword Test operations and call other validation subprocedures: ValidateHTML_WDGValidator, ValidateCSS_W3C_CSS and ValidateHTML_LinkValet. Pass the same set of parameters, but remember to specify different files for saving the results.

Checking for Broken Links with the Web Accessibility Checkpoint

To check a web page for broken links, you can use a web accessibility checkpoint. You can insert it both into keyword tests and script code and you can do this during test recording or at design time:

  • To create a checkpoint during the test recording, click Add Check on the Recording toolbar. Click Web page in the resulting Checkpoint wizard.

  • To insert a new checkpoint in the script code at design time, on the Code Editor toolbar, click Add Checkpoint via Wizard and then click Web page.

  • To insert a new checkpoint into a keyword test at design time, drag the Web Accessibility Checkpoint operation from the Operations list to the test area in the Keyword Test editor.

In the wizard, specify the checkpoint’s parameters:

  • Select the tested web page.

  • Click Accessibility if you create the checkpoint by using the wizard.

  • Select the Check link accessibility check box.

  • Press OK.

If you inserted the checkpoint into a keyword test, TestComplete will add the Web Accessibility Checkpoint operation to the test. If you inserted the checkpoint into a script, TestComplete will generate the checkpoint’ script statements and display them in special dialog box. Using this dialog you can then command the test engine to insert the generated code into your script code, or cancel this operation.

Note: Instead of creating a new checkpoint, you can also modify the Check link accessibility property of an existing Web Accessibility project element and then use this element to perform the check.

For more information on creating and using web accessibility checkpoints, see About Web Accessibility Checkpoints.

See Also

Web Testing - Examples
About Web Accessibility Checkpoints
Testing Web Applications

Highlight search results