Can I store a value from a table search in a variable?

@costea.georgian89

You have messed up your problem. It is very difficult for others to get into it. You should divide your problem into pieces of smaller/manageable size, and then ask others for help.

Let me make a proposal for you.

  1. You have a URL “LeadManager - Login”. You know the credentials to log into it. You can navigate to a Web Page where you find a Table like this:
  2. In the table we can find a row with Email="abchang@hotmail.com" , ID=“598042”
  3. In the table we do not find a row with Email="foobar@gmail.com"

So, @costea.georgian89, could you create a new project. You want to make a test case so that

  • the script searches the table for a row of Email="abchang@hotmail.com" and print its ID value(‘598042’)
  • also the script should be able to find that a row of Email="foobar@gmail.com" is not present in the table, print message “foobar@gmail.com is not our customer”.
  • the script should be able to deal with many other Email addresses as many as you want.

In this practice, I hope you to learn how to modularise your code by introducing methods inside a Test Case and reuse it so that you can process multiple Email addresses.

If you are to make a post about this exercise, please make a ZIP file of the project and share it.

Let me show you a simple example of Test Case which has an internal method named “greeting”. You can repeat calling the method as often as you want.

Test Cases/greeting

import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI

def names = ['Romeo', 'Juliet']
def v

for (name in names) {
    v = greeting(name)
	WebUI.comment(v)
}

def greeting(String name) {
	return "Hello, " + name + "!"
}

This will run as follows:

...
Hello, Romeo!
...
Hello, Juliet!
...

PLS note, the value returned by the call is stored into a variable named v. That is my answer to the question you asked.

Another option of code modularisation is to use WebUI.callTestCase()

Hi @kazurayam Thank you for your info but I got some questions:
1 - Is it not more difficult to make another test case and input methods and reuse?
2 - If I am doing that I will still get the value from the keyword address inputted in the first test case to search in the second test case?
Or if I make a test case where will store the value from table and then I will call in the first test case how I can store the specific valu inpputed from keyword address?
3 - In your answer, I am not looking for abchang@gotmail.com I am looking for an inputted email from keyword upper in this code so here am not understand why I cannot use a simple table check I am asking not say is not the right way how you describe just ask to understand better.
Thank you in advance!

Ok, thank you! I will try and see if it works. Thank you again!

May be more difficult for you. But may be easier for others who are asked questions by you.

If you have a variable in Test Case A and you want to pass the value to next Test Case B, then Test Case A can store the value in a GlobalVariable and Test Case B can read it to get the value. Have a look at this post for reference:

Or, WebUI.callTestCase() returns a value from the callee Test Case to the caller Test Case.

It is totally up to you to solve your problem using “a simple table check”. Nobody stops it. Please write code for yourself.

Just I do not understand what you mean by saying “a simple table check”. The code you presented does not explain to me what “a simple table check” is.

All I can do is to read the codes exposed and try to find how to improve them. If the codes are not expressing your intension, any description in natural language what you want to do doesn’t help.

@kazurayam
Here is the project:

Please ignore Test case 2 there I store some code which you have given to me early on this week. And if you remember you give me a piece of code that help me a lot and that part of the code I want to use to check the value from address and the value from the table. I will start to try to make how you said early in this post.
Here:
groovy.lang.MissingPropertyException

@kazurayam
I said “a simple table check” like from the Example:


and tried on my specific table and that is the reason why I said “a simple table check” because if I am understanding is not so complex code but I am not sure at this moment.

I don’t want to upset you, I just want to understand and that I ask a lot of question.

I understand in essence you want to compare two email addresses:

if(email != tableCellEmail) {
  println("Houston, we have a problem")
}

But I don’t understand after all those posts, where that is supposed to happen.

What strikes me as odd is, you seem unable to clearly state the parameters of the problem in regular text so that leaves me guessing as what it is you need and where you need to do it.

I would however praise you for the amount of info you’ve posted - that’s commendable. Unfortunately, the more you supply, the worse the disconnect seems to be.

I am surprised the code I gave you “failed”. I still don’t know precisely what you mean.

@Russ_Thomas
Thank you for answers!
So I hope this time I will be clear enough I hope.
So I try your code:

String celltext
boolean found = false
for (int column = 0; column < columns_count; column++) {
  celltext = Columns_row.get(column).getText()

  println((((('Cell Value Of row number ' + row) + ' and column number ') + column) + ' Is ') + celltext)

  if (celltext == ExpectedValue) {
    found = true
    println('Lead is present ' + Columns_row.get(2).getText())
    break;
  }
}

if(!found) {
  throw new StepFailedException("Failed to find the email")
}

The expected result will be:
Lead is present

Actual result:
Reason:
com.kms.katalon.core.exception.StepFailedException: Failed to find the email.

So until there is work perfect because is not find the specific email( Here I refer in last comments was fail):
I was refer at the code works for fail one and I don’t understand too why I was said that, sorry for miss information.

Then I tried different methods like:

String celltext
boolean found = false
for (int column = 0; column < columns_count; column++) {
  celltext = Columns_row.get(column).getText()

  println((((('Cell Value Of row number ' + row) + ' and column number ') + column) + ' Is ') + celltext)

  if (celltext == ExpectedValue) {
    found = true
    println('Lead is present ' + Columns_row.get(0).getText())
    break;
  }
}

Same Actual result:
Reason:
com.kms.katalon.core.exception.StepFailedException: Failed to find the email

Then I was thinking I got a problem with finding row.get because my value is maybe possible to not be there in the row.get(0).
So was thinking I got a search field so I can input in the search field the values wich I want to find and the table will return only 1 row on my page and I used this your code + the search value code:

Here I input in the search field

WebUI.setText(findTestObject('Object Repository/Page_LeadManager - Leads/input_Leads_searchInput'), address)

WebUI.sendKeys(findTestObject('Object Repository/Page_LeadManager - Leads/input_Leads_searchInput'), Keys.chord(Keys.ENTER))


//WebUI.click(findTestObject('Object Repository/Page_LeadManager - Leads/input_Modal Title_form-control'))
//WebUI.setText(findTestObject('verifiyelements/Page_LeadManager - Leads/input_Leads_searchInput'), address)
//WebUI.sendKeys(findTestObject('Object Repository/Page_LeadManager - Leads/input_Leads_searchInput'), Keys.chord(Keys.ENTER))
String ExpectedValue = address;

WebDriver driver = DriverFactory.getWebDriver()

//Expected value from Table
WebElement Table = driver.findElement(By.xpath('//*[@id="leadtable"]'))

//To locate table
rows_table = Table.findElements(By.tagName('//th/td'))

// To locate rows of table it will Capture all the rows available in the table
List<WebElement> rows_table = Table.findElements(By.tagName('th'))

// To calculate no of rows In table
int rows_count = rows_table.size()

// Loop will execute for all the rows of the table
Loop: for (int row = 0; row < rows_count; row++) {
    List<WebElement> Columns_row = rows_table.get(row).findElements(By.tagName('a'))

    int columns_count = Columns_row.size()

    println((('Number of cells In Row ' + row) + ' are ') + columns_count)

String celltext
boolean found = false
for (int column = 0; column < columns_count; column++) {
  celltext = Columns_row.get(column).getText()

  println((((('Cell Value Of row number ' + row) + ' and column number ') + column) + ' Is ') + celltext)

  if (celltext == ExpectedValue) {
    found = true
    println('Lead is present ' + Columns_row.get(601657).getText())
    break;
  }
}

if(!found) {
  throw new StepFailedException("Failed to find the email")
}
}

Same actual result:
Reason:
com.kms.katalon.core.exception.StepFailedException: Failed to find the email.

Next, I use to inspect the element and I see the specific row got id=“Row_601861” and I was thinking ok let’s try to see if I input in the code this row number +1( I bold in the sense) the row.get(601861), why I do that because I did some other runs and I saw every time this id=“Row_60186x” will be added +1 and I use the code:

String celltext
boolean found = false
for (int column = 0; column < columns_count; column++) {
  celltext = Columns_row.get(column).getText()

  println((((('Cell Value Of row number ' + row) + ' and column number ') + column) + ' Is ') + celltext)

  if (celltext == ExpectedValue) {
    found = true
    println('Lead is present ' + Columns_row.get(601862).getText())
    break;
  }
}

if(!found) {
  throw new StepFailedException("Failed to find the email")
}


Same actual result:
Reason:
com.kms.katalon.core.exception.StepFailedException: Failed to find the email.

And here I am out of ideas. and here is my issue I cannot find the specific email, and the specific email is the keyword:

package com.costea

import com.kms.katalon.core.annotation.Keyword

public class EmailUtil {

	@Keyword
	static def getMyAddress(){
		return "test" + System.nanoTime() + "@itest.com";
	}
}

I hope now I give you full detailed information about my problem and sorry if I stress you with this but I really need and I don’t know how to handle this, I was tired with Verify Element Text on the page or Verify Text Present no successfully result.

Thank you in advance!

Yes, more info than anyone could possibly expect.

The code looks “okay” but something is wrong somewhere. Let’s try this. And WARNING, this is not meant to fix anything, we’re just going to LOOK to see if you are getting the correct values from the cell:

I am concerned about this line:

celltext = Columns_row.get(column).getText()

If that is not working, then that might be the problem. So change your println to something really simple like this…

celltext = Columns_row.get(column).getText()
println("**************" + celltext)

You can put that in ANY of your trials above. When you run the test case, MAKE SURE you are seeing GOOD values printed out as the loop progresses down the column. If ANYTHING looks bad, tell me why it looks bad.

Lastly, I’d prefer you start with the FIRST block of code above. Let’s stick to ONE loop and work from there. In a few hours, @kazurayam will be back, I’m sure he would appreciate that, too.

I got this:

If is not clear here is screenshot link:
http://joxi.net/L216BRbT0By8BA

There is something wrong with this assignment:

celltext = Columns_row.get(column).getText()

But I don’t know what the problem is, sorry. :frowning:

I will have to duck out. I can’t fathom what this code is doing. I don’t use WebUI code for this kind of thing so I’m probably the worst person to be trying to help you.

I’ll give a shoutout to a few other people:

@grylion54 @ThanhTo @duyluong

(But it’s the weekend, so it might take a while.)

2 Likes

@Russ_Thomas
Thank you for the work you did with me and sorry again for the waste of time not telling you the problem more clearly than the first time. Thank you very much!

1 Like

@costea.georgian89
In the image above you have the code block, if (!found) { within the outer (or higher) for loop. It has to be outside of all the loops. What you are trying to do is loop through all the rows (your outer loop), checking your column comparison (your inner loop), and when you find it, you exit (via the break statement), or if you don’t find it, you fall out of both loops after checking all rows. However, due to the placement of curly brackets, you are still within the outer loop when you are testing for not found and so you are not finished looping through all the rows.

Remove one of the closing curly bracket from the last line in the code block and put it just above the if (!found) { statement.

Align Format

Just a note that your code is not aligned correctly and that could be why you did not see this error. Normally, I align my ending curly brackets with the start of the associated statement. If you highlight the code from String celltext all the way down to just above if (!found) and then hit the tab key, you will have better alignment.

You can check which closing bracket matches the opening bracket by single click on a bracket within KS, its matching one should also highlight.

2 Likes

@costea.georgian89

I checked the Test Case test1 in the Velocify 3.zip you disclosed above. I found a few strange things there. But here I point out one.

At the Line#113 in test1 you wrote:

// To locate rows of table it will Capture all the rows available in the table
List<WebElement> rows_table = Table.findElements(By.tagName('th'))

This line looks very strange to me. Table.findElements(By.tagName('th')) will return a List of <th> tags = columns in the <thead> tag of the table, rather than rows (= <tr> tags in <tbody>). But you named the receiver variable as rows_table. Why?

I am confused with this. I can not follow the code any further.


The test1 opens the web page LeadManager - Login. The page looks like this.


(Just for reference, I attach the zipped snapshot of this page in MHTML here: LeadManager - Leads.mht.zip (237.3 KB). Just unzip this to get a .mht file, drug and drop the file on Chrome browser, then you can see the page reproduced. )

If you have a look at the HTML source of the page, you can easily find that this page contains a <table> tag, which comprises with 50 rows (=<tr> tags inside <tbody>) each of which comprises with 17 columns(=<td> tags).


So, I examined your code. I inserted a line of debug print.

// To locate rows of table it will Capture all the rows available in the table
List<WebElement> rows_table = Table.findElements(By.tagName('th'))

// To calculate no of rows In table
int rows_count = rows_table.size()
println("rows_count=${rows_count}")

When I ran this, I got the following output in the Console.

rows_count=17

The <table> actually has 50 rows(=<tr> tags), but your code says “rows_count is 17”. Your code looks wrong to me.

2 Likes

@costea.georgian89

Let me point out one more issue.

The table in https://lm.prod.velocify.com/Web/Lead/?LoggedIn=1 is logically large. It has nearly 150 rows. It is paginated into 3 views (max 50 rows per view). But the test1 script is coded only to check the 1st page among 3. Obviously not enough.

Possibly you want to go through all rows. I suppose that you would need to modularise your code somehow to manage this complexity. Otherwise your code would be a total mess.

1 Like

I got the same error message even If I change the curly brackets.

But moving the curly brackets was a must. The flow of your program was totally wrong and you would be hard pressed to get good results if your program flow is wrong. As kazurayam has pointed out, there are other issues with your program and moving the curly bracket was only one.

So there are still issues to be reviewed in your code. As kazurayam states, you could try to do the analysis in parts to check when one part is good, only then move onto another part. So, personally, I would comment out the inner for loop for the moment and insert print statements of one or two columns to see if we are moving through the table properly.

Breaking out

Another note, when you break after you have found your match, you want to leave both loops because you have got what you were searching for and don’t need to keep looking. The break by itself only leaves the current loop it is in (the inner loop). So you should put the statement as break Loop; (see below).

if (celltext == ExpectedValue) {
     found = true;
     println('Lead is present...');
     break Loop;
} 

The addition of the Loop label indicates you want to break out to the position where you have the label, Loop, above the outer (or higher) for statement, not just the inner for loop that you were in. I show the Loop label from your own code below, so you can see what I mean.

// Loop will execute for all the rows of the table
Loop:   <<<===== here is the outer label to break to in order to stop searching
for (int row = 0; row < rows_count; row++) {
     List<WebElement> Columns_row ...
Punctuation

I also add semi-colons at the end of all lines that do not start with a WebUI command. I think semi-colons help the compiler to know where to end the instructions, such as
break Loop;
int rows_count = rows_table.size();

I haven’t had any compiler complaints so I have stayed with this format.

2 Likes