Get Last Row of Dynamically Growing Grid

Ask general questions here.
jawg_tc
Posts: 5
Joined: Thu Feb 28, 2013 11:10 pm

Get Last Row of Dynamically Growing Grid

Post by jawg_tc » Thu Feb 28, 2013 11:29 pm

Hi.

Our application uses dynamic grids for data entry. So after a user inserts new data in one of these grids, a new row is inserted at the end of the grid immediately below the last bit of data that the user entered. Additional data would then be set into this new row at the end of the grid.

I am trying to simulate this data entry process programmaticly via a data driven test and I am able to set data successfully the first time through the iteration.

However, I am having trouble setting data on iterations 2+. The problem is that the code I am using to get the newest row for data entry seems to return a cached element. As a result, data entered for iterations 2+ is being set into the first row of the dynamic grid.

Here is an example of the code that I am using to set a value in one of these dynamic grids:

Code: Select all

	public static XfcTests.XfcTestsRepository repo = XfcTests.XfcTestsRepository.Instance;

...

	Element lastCondCodeCell = repo.NonCached.ConditionCodesPanel.FindSingle("./row[last()='True']/cell[last()='True']");
	lastCondCodeCell.Focus();
	Delay.Duration(250, false);        		
	Keyboard.Press(lastCondCodeCell, code);
	repo.EncounterInformation.AccountTextEdit.Focus();
	Delay.Duration(250, false);        	
Please note, the above may be a bit of a round-about way to set data in these fields but I had to resort to setting focus on the element and using Keyboard.Press as more direct methods of setting control attributes did not seem to work.

Also, I set focus on a non-dynamic control after the data entry as a way to trigger our application to then insert the new dynamic row onto the end of the grid, thereby priming it for additional data entry.

If I had to guess, I think that the result of the FindSingle call is being cached. So, I moved the parent container to an application level folder in the control repository and set "Use Cache" to false for this folder. This change had no impact on the behavior.

Please advise, thanks!

User avatar
Support Team
Site Admin
Site Admin
Posts: 12145
Joined: Fri Jul 07, 2006 4:30 pm
Location: Houston, Texas, USA
Contact:

Re: Get Last Row of Dynamically Growing Grid

Post by Support Team » Fri Mar 01, 2013 11:59 am

Hi,

Just two questions, what happens when you refresh the table in Spy after you added a new row, is the new row shown if you expand the table?
How many rows will be found if you search for all rows when using Host.Local.Find<T> and the RxPath to the rows after a new row was added?

Regards,
Markus

jawg_tc
Posts: 5
Joined: Thu Feb 28, 2013 11:10 pm

Re: Get Last Row of Dynamically Growing Grid

Post by jawg_tc » Fri Mar 01, 2013 4:14 pm

Hello,

Thanks for the response.

I don't normally inspect these elements in the data spy as they are being inserted programmaticly.

However, I reproduced the process manually and kept track of the elements in the spy. When I refresh the parent container in the spy, I do indeed see the additional rows. Moreover, I noted that the new row always has the same accessiblename ('NewItem Row'). I updated my code to use this attribute instead of the function last()='True'. Unfortunately, the behavior does not change. Ranorex still seems to inject my content into the original, first row.

Again, it seems like the Ranorex engine is caching the element returned from the FindSingle call and not updating it each time through the iteration. Is there a way to force Ranorex to search the container anew each time?

When I use the Host.Local.Find call, it does show an increased row count.

I even reworked my code again to try to leverage the results of this find call, but the code still isn't setting the correct row in the grid. Here is my updated code:

Code: Select all

IList<Element> results = Host.Local.Find("/form[@controlname='MainForm']/container/container[@controlname='panel1']/container/element/container/container/element[@controlname='conditionCodeGrid']/table/container[@accessiblename='Data Panel']/row");
LogUIAction(ReportLevel.Info, string.Format("Current 'ConditionCode' row count = '{0}'", results.Count.ToString()));
LogUIAction(ReportLevel.Info, string.Format("Setting 'ConditionCode' with '{0}'", code));
		Element lastCondCodeCell = null;
if (results.Count > 0)
{
  		//Element lastCondCodeCell = repo.TruCodeNonCached.ConditionCodesPanel.FindSingle("./row[last()='True']/cell[last()='True']");
  		//Element lastCondCodeCell = repo.TruCodeNonCached.ConditionCodesPanel.FindSingle("./row[@accessiblename='NewItem Row']/cell[last()='True']");				
  		foreach	(Element elm in results)
  		{
  			string accessiblename = elm.GetAttributeValueText("AccessibleName");
  			LogUIAction(ReportLevel.Info, string.Format("Current 'ConditionCode' row is '{0}'", accessiblename));
  			if (accessiblename == "NewItem Row")
  			{
  				lastCondCodeCell = elm.FindSingle("./cell[2]");
  			}
  		}
}
if (lastCondCodeCell != null)
{
  		lastCondCodeCell.Focus();
    	Delay.Duration(250, false);        		
	Keyboard.Press(lastCondCodeCell, code);
	repo.EncounterInformation.AccountTextEdit.Focus();
    	Delay.Duration(250, false);        		
  	}
else
{
	LogUIAction(ReportLevel.Error, "Failed to locate last ConditionCode row");
}
Here is the relevant log output from this section of code:


01:36.105 Info User itemCurrent 'ConditionCode' row count = '1'
01:36.176 Info User itemSetting 'ConditionCode' with 'AA'
01:36.275 Info User itemCurrent 'ConditionCode' row is 'NewItem Row'
01:38.773 Info User itemCurrent 'ConditionCode' row count = '2'
01:38.818 Info User itemSetting 'ConditionCode' with 'BB'
01:38.936 Info User itemCurrent 'ConditionCode' row is 'Row 1'
01:39.034 Info User itemCurrent 'ConditionCode' row is 'NewItem Row'

User avatar
Support Team
Site Admin
Site Admin
Posts: 12145
Joined: Fri Jul 07, 2006 4:30 pm
Location: Houston, Texas, USA
Contact:

Re: Get Last Row of Dynamically Growing Grid

Post by Support Team » Mon Mar 04, 2013 3:10 pm

Hi,

Ranorex doesn't use caching when you use "Host.Local.Find(...)".
When I use the Host.Local.Find call, it does show an increased row count.
If this is the case the results should also contain the added row, otherwise the row count wouldn't be increased, so what happens if you would directly access the last found row with "results[Count-1]"?
If this shouldn't work could you please post us two Ranorex snapshot files of these rows? One before and one after you added a new one.
Following link will show you how to generate a snapshot file:
Creating Ranorex Snapshot Files.

Regards,
Markus

jawg_tc
Posts: 5
Joined: Thu Feb 28, 2013 11:10 pm

Re: Get Last Row of Dynamically Growing Grid

Post by jawg_tc » Tue Mar 05, 2013 11:49 pm

Hi.

It's still not working right.

I've attached the two snapshot files requested (both for before the code attempts to set the data).

Here is a snapshot of the code I am running now:

Code: Select all

IList<Element> results = Host.Local.Find("/form[@controlname='MainForm']/container/container[@controlname='panel1']/container/element/container/container/element[@controlname='conditionCodeGrid']/table/container[@accessiblename='Data Panel']/row");
LogUIAction(ReportLevel.Info, string.Format("Current 'ConditionCode' row count = '{0}'", results.Count.ToString()));
LogUIAction(ReportLevel.Info, string.Format("Setting 'ConditionCode' with '{0}'", code));
Element lastCondCodeCell = null;
if (results.Count > 0)
{        		
	lastCondCodeCell = results[results.Count - 1].Children[1];
	LogUIAction(ReportLevel.Info, string.Format("Setting value on ConditionCode cell '{0}' with ID {1}", 
	                                            lastCondCodeCell.GetAttributeValueText("AccessibleName"),
	                                            lastCondCodeCell.ToString()));
}
if (lastCondCodeCell != null)
{
	lastCondCodeCell.Focus();
	Delay.Duration(250, false);        		
	Keyboard.Press(lastCondCodeCell, code);
	Keyboard.Press(lastCondCodeCell, "{return}");
	repo.EncounterInformation.AccountTextEdit.Focus();
	Delay.Duration(250, false);        		
}
Here are the log entries generated by this run:
06:59.684 Info Current 'ConditionCode' row count = '1'
06:59.764 Info Setting 'ConditionCode' with 'AA'
07:00.085 Info Setting value on ConditionCode cell 'Cond Code row -2147483647' with ID {Cell:Cond Code row -2147483647}
14:38.811 Info Current 'ConditionCode' row count = '2'
14:38.901 Info Setting 'ConditionCode' with 'BB'
14:39.081 Info Setting value on ConditionCode cell 'Cond Code row -2147483647' with ID {Cell:Cond Code row -2147483647}

Thanks.
You do not have the required permissions to view the files attached to this post.

User avatar
Support Team
Site Admin
Site Admin
Posts: 12145
Joined: Fri Jul 07, 2006 4:30 pm
Location: Houston, Texas, USA
Contact:

Re: Get Last Row of Dynamically Growing Grid

Post by Support Team » Wed Mar 06, 2013 1:31 pm

Hi,

Thanks for the snapshots!
As I can see from the snapshot and the output of your code it worked as expected, why do you think that it didn't work correctly?
As I can see from the snapshot the last row, the new added one, always has the same "AccesibleName", it is always "Cond Code row -2147483647".
Could you add this code and check if Ranorex clicks on the right Cell?
lastCondCodeCell.As<Cell>().Click();
Regards,
Markus

jawg_tc
Posts: 5
Joined: Thu Feb 28, 2013 11:10 pm

Re: Get Last Row of Dynamically Growing Grid

Post by jawg_tc » Wed Mar 06, 2013 3:01 pm

I will add the code you requested.

The reason I think that the tool isn't working correctly is that the data is always entered into the first row of the Grid and not the last row (where new content needs to be added).

Would it help if I provided a video capture of the test?

Thanks,
Jake

jawg_tc
Posts: 5
Joined: Thu Feb 28, 2013 11:10 pm

Re: Get Last Row of Dynamically Growing Grid

Post by jawg_tc » Wed Mar 06, 2013 4:24 pm

Thank you!

The Click command did the trick. I guess Focus doesn't really work correctly in the context of our application.

Thank you again.