Extracting HTML tables from Ranorex table object

Ask general questions here.
User avatar
Aracknid
Posts: 342
Joined: Tue Aug 10, 2010 3:23 pm
Location: Toronto, Ontario, Canada

Extracting HTML tables from Ranorex table object

Post by Aracknid » Fri Dec 09, 2016 11:21 pm

Hi,

Just wondering if it is possible to have a Ranorex table object and dump ALL it's HTML to a file.

I've already written the code to do it and noticed that if I take the innerhtml of the table, I get the structure within the table tags, but not the table tags. Thus I miss out on any formatting within the table tags themselves.

If I grab the parent of the table, and dump its innerhtml, then I get the full table with its table tags, but I may also get other elements within the parent that I don't want.

Any other way to get it that I'm not aware of.

FYI: I store the HTML and then compare to it later when I run the test, which will allow me to validate the tables are identical quickly and no data is missing.

Thanks,

Aracknid

NOTE: Using Ranorex 5.4.2

User avatar
odklizec
Ranorex Guru
Ranorex Guru
Posts: 3914
Joined: Mon Aug 13, 2012 9:54 am
Location: Zilina, Slovakia

Re: Extracting HTML tables from Ranorex table object

Post by odklizec » Mon Dec 12, 2016 8:36 am

Hi,

Have you considered using Ranorex snapshots for comparing HTML tables? It's described here:
http://www.ranorex.com/support/user-gui ... html#c8203
I'm using it and it works quite well. I just added some code to examine individual table cells if they contain some inner webelements and if they do, they are validated as well. Here is the code I'm currently using:

Code: Select all

		/// <summary>
		/// This method compares the content of actual HTML table with reference table stored in snapshot file.
		/// </summary>
		/// <param name="repoItem">HTML table repo element</param>
		/// <param name="filename_ReferenceTableSnapshot">reference snapshot file</param>
		/// <param name="customLogMessage">custom report log string</param>
		/// <param name="compareSubtables">if true, enables comparison of sub-tables</param>
        const string NullString = "(null)";
        public void TableContentEqual_Validate(Ranorex.Adapter repoItem, string filename_ReferenceTableSnapshot, string customLogMessage)
        {
        	var error = 0; 
        	// check if snapshot file exists
        	// don't forget the snapshot needs to be extracted (unzipped) before being used!!!  
        	const string fileNotExists = "The given file does not exist: {0}";
        	if (!System.IO.File.Exists(filename_ReferenceTableSnapshot))
        	{
        		throw new Ranorex.RanorexException(string.Format(fileNotExists, filename_ReferenceTableSnapshot));
        	}
        	
        	// restore table from snapshot
        	var snap = Ranorex.Core.ElementSnapshot.DeserializeXml(System.IO.File.ReadAllText(filename_ReferenceTableSnapshot));
        	Ranorex.TableTag refTable = null;
        	try
        	{
        		refTable = snap.Element;
        	}
        	catch
        	{
        		throw new Ranorex.RanorexException("Table could not be created from snapshot");
        	}
        	// cast repoItem to Table
        	var tableAdapter = repoItem.As<Ranorex.TableTag>();
        	if (tableAdapter==null)
        	{
        		throw new Ranorex.RanorexException("Repo-item could not be accessed");
        	}
        	
        	// check if rowcount is identical
        	IList<TrTag> iListCurRows = tableAdapter.FindDescendants<TrTag>();
        	int rowCountCur = iListCurRows.Count;
        	IList<TrTag> iListRefRows = refTable.FindDescendants<TrTag>();
        	int rowCountRef = iListRefRows.Count;
        	if (rowCountCur != rowCountRef)
        	{
        		throw new Ranorex.RanorexException(String.Format ("Tables do not have same number of rows (CurTable: {0} vs. RefTable: {1})", rowCountCur, rowCountRef));
        	}
       	
		    // run through table-rows  
		    for (int iRow = 0; iRow <= rowCountCur - 1; iRow++)  
			{
				IList<Ranorex.WebElement> cellsInCurRow = iListCurRows[iRow].FindChildren<Ranorex.WebElement>();  
				IList<Ranorex.WebElement> cellsInRefRow = iListRefRows[iRow].FindChildren<Ranorex.WebElement>();  
		       
		        // check if number of cur&ref cells is identical in current row  
        		if (cellsInCurRow.Count != cellsInRefRow.Count)
        		{
        			throw new Ranorex.RanorexException(String.Format("Table-Rows do not have same number of cells (CurRow: {0} vs. RefRow: {1})", cellsInCurRow.Count, cellsInRefRow.Count));
        		}
		  
		        // run through cells in current row  
		        for (int iCol = 0; iCol <= cellsInCurRow.Count - 1; iCol++)  
		        {  
					IList<Ranorex.WebElement> childrenInCurCell= cellsInCurRow[iCol].FindChildren<Ranorex.WebElement>();  
					IList<Ranorex.WebElement> childrenInRefCell = cellsInRefRow[iCol].FindChildren<Ranorex.WebElement>();
					
					// check if number of cells' children elements is identical in cur&ref cell 
					if (childrenInCurCell.Count != childrenInRefCell.Count)
	        		{
						Report.Screenshot(ReportLevel.Failure,"Failure",String.Format("Row-Cell (row: {2}/col.:{3}) do not have same number of children elements (CurCell: {0} vs. RefCell: {1})",childrenInCurCell.Count, childrenInRefCell.Count, iRow, iCol),cellsInCurRow[iCol].Element,true,null);
						throw new Ranorex.RanorexException();
	        		}		        

					// if cell has no children, get inner text from parent element...
					if (childrenInCurCell.Count == 0)
					{
						string aCurText = new WebElement(cellsInCurRow[iCol]).InnerText;  
						string aRefText = new WebElement(cellsInRefRow[iCol]).InnerText;
			            string validationMessage = string.Empty;  
			            if (string.IsNullOrEmpty(customLogMessage))  
			            {  
			                validationMessage = String.Format("Comparing content of cell (row: {2}/col.:{3}) (found:'{0}', expected: '{1}')", aCurText, aRefText, iRow, iCol);  
			            }  
			            else  
			            {  
			                validationMessage = customLogMessage;  
			            }  
			  
			            // validate whether current text and expected text are identical  
	        			try
						{
							// validate whether current text and expected text are identical
							// use Ranorex.Validate.AreEqual only in case of simple validations, otherwise, it slows test execution
							// enable/disable CustomerConfiguration (per selected location)
							//Regex regex = new Regex(aCurText+"\\s*$");
							//Match match = regex.Match(aRefText ?? "",);
							//if (!match.Success)
							if ((aCurText!=null) & (aRefText!=null))
							{
								aCurText = Regex.Replace(aCurText, @"^\s+|\s+$", "");
								aRefText = Regex.Replace(aRefText, @"^\s+|\s+$", "");
							}
							if (aCurText != aRefText)
	    	    			{
								cellsInCurRow[iCol].EnsureVisible();
	    	    				Report.Screenshot(ReportLevel.Failure,"Failure",validationMessage,cellsInCurRow[iCol],true,null);
								throw new RanorexException();
	    	    			}
						}
						catch(RanorexException)
						{
							error = -1;
						}
					}
					else
					{
						for (int iCell = 0; iCell <= childrenInCurCell.Count - 1; iCell++)
						{
							string aCurText = new WebElement(childrenInCurCell[iCell]).InnerText;  
							string aRefText = new WebElement(childrenInRefCell[iCell]).InnerText; 	
							
				            string validationMessage = string.Empty;  
				            if (string.IsNullOrEmpty(customLogMessage))  
				            {  
				                validationMessage = String.Format ("Comparing content of cell (row: {2}/col.:{3}) (found:'{0}', expected: '{1}')", aCurText, aRefText, iRow,iCell);  
				            }  
				            else  
				            {
				                validationMessage = customLogMessage;  
				            }
				  
				            // validate whether current text and expected text are identical  
		        			try
							{
								// validate whether current text and expected text are identical
								// use Ranorex.Validate.AreEqual only in case of simple validations, otherwise, it slows test execution
								//Regex regex = new Regex(aCurText+"\\s*$");
								//Match match = regex.Match(aRefText ?? "",);
								//if (!match.Success)
								if ((aCurText!=null) & (aRefText!=null))
								{
									aCurText = Regex.Replace(aCurText, @"^\s+|\s+$", "");
									aRefText = Regex.Replace(aRefText, @"^\s+|\s+$", "");								
								}
								if (aCurText != aRefText)
		    	    			{
									cellsInCurRow[iCol].EnsureVisible();
		    	    				Report.Screenshot(ReportLevel.Failure,"Failure",validationMessage,cellsInCurRow[iCol],true,null);
									throw new RanorexException();
		    	    			}
							}
							catch(RanorexException)
							{
								error = -1;
							}
						}
					}
		        }
			}
        	if (error == 0)
        	{
	        	// Log success
	        	Ranorex.Report.Log (ReportLevel.Success, "Reference and actual table '" + repoItem.ToString() + "' validated OK.");
        	}	
        }
True, this code only validates InnerText of each table cell/webelement and not their formatting. So if you need to check the formatting as well, you will most probably have to change the above code. In any case, using snapshots for validating HTML tables is a time-saver ;)
Pavel Kudrys
Ranorex explorer at Descartes Systems

Please add these details to your questions:
  • Ranorex Snapshot. Learn how to create one >here<
  • Ranorex xPath of problematic element(s)
  • Ranorex version
  • OS version
  • HW configuration