Match Data from Spreadsheet to Search Results in Table, Click Correct one

I have a page that has search results that may come up with a bunch of results depending on the name used, I’d like to be able to select the specific one I want (even though i’ll likely use both first and last names removing the need, i’d like the option).

Code for the search results table:

    <!-- ngIf: searchResults.customers && searchResults.customers.length > 0 --><div class="col-sm-4 ng-scope" ng-if="searchResults.customers &amp;&amp; searchResults.customers.length > 0">
        <div class="panel panel-default animated fadeIn">
            <div class="panel-heading">
                <h4><i class="fa fa-users"></i> Contacts</h4>
            </div>

            <!-- List group -->
            <div class="list-group">
                <!-- ngRepeat: foundCustomer in searchResults.customers --><a href="javascript:void(0)" class="list-group-item ng-scope" ng-repeat="foundCustomer in searchResults.customers" ng-click="customerClicked(foundCustomer)">
                    <h4 class="list-group-item-heading ng-binding">
                        <!-- ngIf: ::foundCustomer.is_cip_user --> Princess
                        Belle
                    </h4>
                    <p class="list-group-item-text ng-binding">555-555-5555</p>
                    <!-- ngIf: foundCustomer.company_name --><p class="list-group-item-text ng-binding ng-scope" ng-if="foundCustomer.company_name">
                        Disney<br>
                        
                    </p><!-- end ngIf: foundCustomer.company_name -->
                </a><!-- end ngRepeat: foundCustomer in searchResults.customers --><a href="javascript:void(0)" class="list-group-item ng-scope" ng-repeat="foundCustomer in searchResults.customers" ng-click="customerClicked(foundCustomer)">
                    <h4 class="list-group-item-heading ng-binding">
                        <!-- ngIf: ::foundCustomer.is_cip_user --> Princess
                        Jasmine
                    </h4>
                    <p class="list-group-item-text ng-binding">555-555-5555</p>
                    <!-- ngIf: foundCustomer.company_name --><p class="list-group-item-text ng-binding ng-scope" ng-if="foundCustomer.company_name">
                        Disney<br>
                        
                    </p><!-- end ngIf: foundCustomer.company_name -->
                </a><!-- end ngRepeat: foundCustomer in searchResults.customers --><a href="javascript:void(0)" class="list-group-item ng-scope" ng-repeat="foundCustomer in searchResults.customers" ng-click="customerClicked(foundCustomer)">
                    <h4 class="list-group-item-heading ng-binding">
                        <!-- ngIf: ::foundCustomer.is_cip_user --> Princess
                        Leia
                    </h4>
                    <p class="list-group-item-text ng-binding">555-555-5555</p>
                    <!-- ngIf: foundCustomer.company_name --><p class="list-group-item-text ng-binding ng-scope" ng-if="foundCustomer.company_name">
                        Disney<br>
                        
                    </p><!-- end ngIf: foundCustomer.company_name -->
                </a><!-- end ngRepeat: foundCustomer in searchResults.customers -->
            </div>
        </div>
    </div><!-- end ngIf: searchResults.customers && searchResults.customers.length > 0 -->

    <!-- ngIf: searchResults.vehicles && searchResults.vehicles.length > 0 -->

    <!-- ngIf: searchResults.vehicles && searchResults.vehicles.length == 0 && searchResults.customers && searchResults.customers.length == 0 && searchResults.businesses && searchResults.businesses.length == 0 -->

</div>

I’d like to select based on their name in this case. Currently it is hard coded to just choose which option i want which prevents me from also being able to validate the chosen person is the correct person.

Here is what the table looks like on site:

Here is the code in Katalon when just selecting an option outright:
WebUI.click(findTestObject(‘Object Repository/Page_SOMETHING/Page_SOMETHING - Service/h4_Tom’))

Here is code I wrote today to load in my data (which works) and it performs the search, but i can’t find a way to point to the name in the results…

import static com.kms.katalon.core.checkpoint.CheckpointFactory.findCheckpoint
import static com.kms.katalon.core.testcase.TestCaseFactory.findTestCase
import static com.kms.katalon.core.testdata.TestDataFactory.findTestData
import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject
import com.kms.katalon.core.checkpoint.Checkpoint as Checkpoint
import com.kms.katalon.core.cucumber.keyword.CucumberBuiltinKeywords as CucumberKW
import com.kms.katalon.core.mobile.keyword.MobileBuiltInKeywords as Mobile
import com.kms.katalon.core.model.FailureHandling as FailureHandling
import com.kms.katalon.core.testcase.TestCase as TestCase
import com.kms.katalon.core.testdata.TestData as TestData
import com.kms.katalon.core.testobject.TestObject as TestObject
import com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WS
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
import internal.GlobalVariable as GlobalVariable

TestData searchData = findTestData(‘Data Files/WO_Object_Search’)

firstName = searchData.internallyGetValue(‘firstName’, 1)

lastName = searchData.internallyGetValue(‘lastName’, 1)

searchResults = ’ ‘+firstName+’ ‘+lastName+’ ’

WebUI.openBrowser(‘’)

WebUI.navigateToUrl(‘https://something.com/login’)

WebUI.setText(findTestObject(‘Page_SOMETHING/input_Sorry something went wro’), ‘something@gmail.com’)

WebUI.setEncryptedText(findTestObject(‘Object Repository/Page_SOMETHING/Page_SOMETHING/input_Sorry something went wro_13’), ‘apassword’)

WebUI.click(findTestObject(‘Object Repository/Page_SOMETHING/Page_SOMETHING/input_Sorry something went wro_14’))

WebUI.click(findTestObject(‘Object Repository/Page_SOMETHING/Page_SOMETHING - Service/div_concat(id( beamerOverlay’))

for (def index : (0…searchData.getRowNumbers() - 1)) {
firstName = searchData.internallyGetValue(‘firstName’, index)

lastName = searchData.internallyGetValue('lastName', index)
searchResults = '                              '+firstName+'                             '+lastName+'                         '

WebUI.click(findTestObject('Object Repository/Page_SOMETHING/Page_SOMETHING - Service/a_New'))

WebUI.setText(findTestObject('Object Repository/Page_SOMETHING/Page_SOMETHING - Service/input_HERE_job-wizard-search-b'), 
    (firstName + ' ') + lastName)

WebUI.verifyElementAttributeValue(findTestObject('woResults', [('#text') : searchResults]))

WebUI.click(findTestObject('Object Repository/Page_SOMETHING/Page_SOMETHING - Service/h4_Impossible Grandam'))

WebUI.setText(findTestObject('Object Repository/Page_SOMETHING/Page_SOMETHING - Service/textarea_Overview_form-control'), 
    'Overview box')

WebUI.click(findTestObject('Object Repository/Page_SOMETHING/Page_SOMETHING - Service/label'))

WebUI.setText(findTestObject('Object Repository/Page_SOMETHING/Page_SOMETHING - Service/input_Hours  hours_variable'), '6700')

WebUI.selectOptionByValue(findTestObject('Page_SOMETHING/Page_SOMETHING - Service/select_Select a Turtle'), 'object:530', 
    true)

WebUI.setText(findTestObject('Object Repository/Page_SOMETHING/Page_SOMETHING - Service/input_Stuff'), 
    '2')

WebUI.click(findTestObject('Object Repository/Page_SOMETHING/Page_SOMETHING - Service/label_Credit'))

WebUI.click(findTestObject('Object Repository/Page_SOMETHING/Page_SOMETHING - Service/label_Text'))

WebUI.click(findTestObject('Object Repository/Page_SOMETHING/Page_SOMETHING - Service/input_Phone_btn btn-success bt'))

WebUI.click(findTestObject('Object Repository/Page_SOMETHING/Page_SOMETHING - Service/button_Close'))

WebUI.click(findTestObject('Object Repository/Page_SOMETHING/Page_SOMETHING - Service/a_StuffAgain'))

}

WebUI.closeBrowser()

Note I was using a name with Tom earlier hence that showing instead of a princess. Yes i will validate with first and last name, but again I want the results to show more than one currently while selecting the correct one (it will have access to the last name field in the data spreadsheet). Also, altered some name stuff but that is just for work reasons.

This is more so I can understand how to scan the results and what to use to find the result i want to click.

Thanks.

If I understand, you want the following:

  • Search for a name
  • Then click the name on the page if its there

I would create an object in the test and base this upon the name value. Then wrap this into an if statement to look for the object and if it’s able to find it inside the if statement click it.

import com.kms.katalon.core.testobject.TestObject


TestObject selectNameObj = new TestObject("objectName")
selectNameObj.addProperty("xpath", ConditionType.EQUALS, '//*/div[@class="list-group"]/!/h4/![contains(text(),searchResults)]

not sure if that xpath will work, might need to play with it a bit. You can inspect in chrome then hit ctrl + F and play with the xpath. If you do it right it will highlight yellow. Note I put in “searchResults” for text. I based this on your code if that is what you are looking for.

then something like this for the if statement:

if (WebUI.verifyElementPresent(selectNameObj, 0, FailureHandling.CONTINUE_ON_FAILURE)) {
 WebUI.click(selectNameObj)
} else {
 WebUI.comment(selectNameObj + " Not found")
}

Hopefully that is helpful.

1 Like

This looks great and will test next chance i get today, however the object will need to be lastName and firstName variables, as well as extra spacing. Note in the site code the name is parsed i counted it has spacers in the name 30 in front, 29 inbetween and 25 at the end.

In my OP my code (which got broken up not sure why) has a first and lastName variable to test that exact thing, i defs didn’t know how to point to it so i’m hoping that helps, but i’m worried the TestObject(“objectName”) might not work. Though, i guess I can pass a variable into objectName. Hm might have worked that in my head.

I really appreciate you looking at this and posting. I’ll let you know if that helps me solve the issue. Thanks again.

the white space shouldn’t matter since it’s looking for “contains” easily way to test if that object will recognize would be to go to the page you are testing with the names in chrome. Right click and inspect the page. then ctrl + f
this pulls up a search box at the bottom. paste this:

//*/div[@class="list-group"]/!/h4/![contains(text(),Princess Belle)

if it highlights yellow, it’s working. If not you’ll need to do some work with it. with the inspect page open in chrome you can right click the name of the princess and hit inspect again. This will jump to that part in the page’s code. moving your mouse around on the page will highlight the element on the inspect page. if you find the princess you want you can right click and copy xpath. You can then modify the xpath to include the contains piece. You may know all this, but just incase and for future readers I wanted to spell it out.

If you need help with the xpath, feel free to post it here and I’ll do what I can.

Example:

If you where on Amazon (note it’s case sensitive) I can find something and literally just change the text for my contains path. Which is what you would be doing passing the variable. You’ll see the last two examples, the xpath is the exact same other then some text. It doesn’t care about all of the text, just if the text contains what you specify.

but yeah let me know and I’ll do what I can. I’m not a programmer. I’ve been a tester since 2009 and taught myself katalon and java best I could.

1 Like

Hi B_L i did what you suggested to test it quickly in browser which is a fantastic idea! However, this xpath didn’t return results. I opened all blocks in the console as well to make sure that wasn’t the issue. Here’s an image of the test trial of that.

image

Here is the xpath when copying direclty from Princess Belle path: //*[@id=“search_results_container”]/div/div/div/div[2]/a[1]/h4/text()

EDIT: Quickly to let you know the image does have //* removed from the start that’s because i was trying both. I’ve adjusted it multiple times, i’m wondering if we can use the list-group class and the search_results_container to help it.

EDIT 2: I also tried manipulating the xpath while looking in the debug window and copying xpaths. Nothing seems to work, i obviously can’t have a[1] as that refrences the first part of the table, and each result has a diff number so i could use a variable. But nothing shows up here is what i tried: //*[@id=“search_results_container”]/!/h4/![contains(text(), Princess Belle) and variations thereof. Seems to not find it no matter how i try, with class with id, and changing the h4 portion. Which reminds me, what is the /!/h4! the ! portion is that a way to say get the path before like */ ?

EDIT 3: Sorry for editing so much was tinkering and realized your code had a missing ] i believe. So I added that and tried again and no luck, also i tried the exact xpath as it copied and it still didn’t work even with the fixed bracket.

there’s a * affter the 2 // but it made it go italic.
//[@id=“search_results_container”]/div/div/div/div[2]/a[1]/h4/[contains(text(),Princess Belle)] is the path i tried, could not highlight anything. I also retried yours ///div[@class=“list-group”]/!/h4/![contains(text(),Princess Belle)] with the ] i believe that’s in the right place. Really hate xpath but i’m quite sure it’s our site, our devs really bury things they don’t want it easy to crawl / scrape data. Has made my jaunt into automation a hell.

Adding another just so you have information and anyone else that might have answers can see.

I’ve added a test just to see if it can highlight and it can with a few changes, but not with contains in anyway so it’s not what i need. But maybe it will help someone find out how to get this contains to work.

image

or if i use a simpler version it will actually grab not just the headers, but maybe grab text.

image

note, none have contains this was just to test highlighting in this area. I am using the @id=“search_results_container”

Hope this information helps.

Thanks in advance.

Sorry for the delayed response, been busy :slight_smile:

This helps:

//*[@id=“search_results_container”]/div/div/div/div[2]/a[1]/h4/text()

With this a few things. First if you go with text for some reason Katalon seems to not like that. Also you will notice the “a” it has “a[1]” meaning the first a. so we remove the 1 and it will look for any a

//*[@id=“search_results_container”]/div/div/div/div[2]/a/h4/text()

We can then apply the contains like this

//*[@id=“search_results_container”]/div/div/div/div[2]/a/h4/text()[contains(.,"Princess Belle")

Note I have “.” because we already call out we are looking for the text. please try this xpath. this SHOULD allow you to highlight the text. However this will still not be enough to identify the object so I would also add in parent. like this:

//*[@id=“search_results_container”]/div/div/div/div[2]/a/h4/text()[contains(.,"Princess Belle")/parent::a

This SHOULD highlight the a for you. it will be a very small highlight but should work for your purposes. Let me know. Ideally if this works you should then be able to change it to your variable and use it.

//*[@id=“search_results_container”]/div/div/div/div[2]/a/h4/text()[contains(.,searchResults)

No worries on response time, I get you might be busy with life. I do appreciate you swinging by. THis text finding seems impossible, everything i have researched either says katalon can’t do text which would be weird as it’s based off of selenium. If i cannot find text with it the software becomes useless as this is the biggest tester.

I actually tried//*[@id=“search_results_container”]/div/div/div/div[2]/a/h4/text()[contains(.,“Princess Belle”)] last night after finding you in search results in another thread. That can’t find anything. It shows zero results, and when i add the /parent::a it changes nothing. If i remove the contains it finds handful of results as per my previous post, but that contains instantly removes all results.

Just shows up empty, even when i can clearly see Princess Belle in the elements section of the debug console in chrome.

I have added the parent portion but that doesn’t help either. //*[@id=“search_results_container”]/div/div/div/div[2]/a/h4/text()[contains(.,“Princess Belle”)]/parent::a

ok that is my fault…so contains will look for each exact letter, case, space etc within the " ". So we can’t pass a value with spaces like that…however this should DEFINITELY work :slight_smile:

Try this:

[@id=“search_results_container”]/div/div/div/div[2]/a/h4/text()[contains(.,“Princess") and contains(.,"Belle”)]/parent::a

That should highlight your a and will work in katalon. Give it a shot and if it highlights yellow you are good to go. To pass values you will need two variables one for first and one for last in the case of two word name.

you have this in your code:

searchResults = '     '+firstName+'    '+lastName+'    '

So try this for the name:

TestObject selectNameObj = new TestObject("objectName")
selectNameObj.addProperty("xpath", ConditionType.EQUALS, '[@id=“search_results_container”]/div/div/div/div[2]/a/h4/text()[contains(.,' + firstName + ') and contains(.,' + lastName + ')]/parent::a')

Example of how I got it to work:
Went to a page with text see it highlighted below with its xpath:

Next I did an “and contains” to look for two completely different words.

lastly I did the parent thing to highlight the p in this case, in yours it would be the a I believe.

I went here to find out about the double contains:

and I was on this page when I was playing with the xpath:

If you go there and use this xpath it will highlight the p for you:
//*[@id=“answer-18885071”]/div/div[2]/div[1]/p/text()[contains(.,“This”) and contains(.,“efficient”)]/parent::stuck_out_tongue:

Sorry about the initial bad advice :S please let me know if this works. Solving this stuff is like a puzzle for me and I can’t stand when I am unable to solve one lol.

1 Like

EDIT: !! It turns out your code had a wrong xpath somehow? that might be on me or the site here formatting weird, i grabbed xpath again and added your contains portion to test that out… BAM! we have a winner. Thought you might like to see the results. No need for parent either on the one i wrote, though i could maybe add that back in, i was typing it by hand when it instantly highlighted the one princess.

Thank you so, so much B_L. Glad you like puzzles, and again i really appreciate you coming back each time to check and try to help more.

Results from your hard work.

Just have to add to my Test Case and see how it works out.

Edited. I keep finding my errors. So i’ll call this good for now while i try to implement the code without posting over and over.

04-09-2019 02:32:16 PM Test Cases/Create WOs

Elapsed time: 1m - 42.722s

Test Cases/Create WOs FAILED.
Reason:
com.kms.katalon.core.exception.StepFailedException: com.kms.katalon.core.webui.exception.WebElementNotFoundException: Web element with id: ‘objectName’ located by ‘By.xpath: //*[@id=“search_results_container”]/div/div/div/div[2]/a/h4/text()[contains(.,Bruce) and contains(.,Willis)]’ not found

My Code:

for (def index : (0…searchData.getRowNumbers() - 1)) {
firstName = searchData.internallyGetValue(‘firstName’, index)

lastName = searchData.internallyGetValue('lastName', index)


WebUI.click(findTestObject('Object Repository/Page_GOOGLE/Page_GOOGLE - Service/a_New'))

WebUI.setText(findTestObject('Object Repository/Page_GOOGLE/Page_GOOGLE - Service/input_HERE_job-wizard-search-b'), 
    (firstName + ' ') + lastName)

selectNameObj.addProperty("xpath", ConditionType.EQUALS, '//*[@id="search_results_container"]/div/div/div/div[2]/a/h4/text()[contains(.,' + firstName + ') and contains(.,' + lastName + ')]')

if (WebUI.verifyElementPresent(selectNameObj, 0, FailureHandling.CONTINUE_ON_FAILURE)){
	WebUI.click(selectNameObj)
}else{
WebUI.comment(selectNameObject + "Not Found")
}

Picture of how the IDE has it formatted in case that helps.

I’m thinking it’s passing the names but not passing them correctly for some reason, not 100% on this one.

EDIT: Found it couldn’t find using that, i had to add in " ’ " to the expression like so:

selectNameObj.addProperty(“xpath”, ConditionType.EQUALS, ‘//*[@id=“search_results_container”]/div/div/div/div[2]/a/h4/text()[contains(.,’ + “'” + firstName + “'” + ‘) and contains(.,’ + “'” + lastName + “'”+ ‘)]’)

Now on the error output i note it shows the final ’ in the search i’m wondering if it’s using that… either way, using this method will work in browser as it needs the ‘bruce’.

There are two matching results, could that be an issue? i’d have it click first result to match until i have extra identifiers added later.

Awesome I’m glad you are getting further. All good on the xpath, that is why I posted examples :slight_smile: if I don’t have access to your page I have to kinda guess at the path. I don’t think /parent::a would work though for your situation anyway. looking at the last screenshot might need /parent::h4. That might be the reason for the error, I just know everytime I try to click or locate an object that is “text()” in katalon it doesn’t find it. I have to refer to the actual…erm div? element? whatever the proper term is. That makes sense though that it would need the quotes around it in the xpath. Try this one:

selectNameObj.addProperty(“xpath”, ConditionType.EQUALS, ‘//*[@id=“search_results_container”]/div/div/div/div[2]/a/h4/text()[contains(.,"’ + firstName + ‘") and contains(.,"’ + lastName + ‘")]’)/parent::h4

you could also try it without the parent part at the end but I believe Katalon wants the h4 and not the text.

note what I did here, you had an additional + “’” + on each side of name we can put this before and after instead of doing the additional pluses. Also I believe in xpath you’ll want " not ’

Give that a shot and let me know if that works. As far as the bruce…if it’s a different last name it should be able to pick it up because its looking for containing both since we are using “and” and not “or” in the xpath…“should” I say :wink:

Give that a go and let me know and we’ll go from there.

Sadly I had already switched the xpath to “xpath”.

I’ve changed the thing you changed which is to remove my extra + needed to get the ’ around the names… but that doesn’t help. I had a way to do that, and while more complex, your method just cleans up the code and it changes it from ‘Bruce’ to “Bruce” being displayed in the error message so it’s not placing single ’ it’s placing the " around the name. Unless i missed something else, i don’t see a difference.

Mine now with your " added in:

selectNameObj.addProperty(“xpath”, ConditionType.EQUALS, ‘//*[@id=“search_results_container”]/div/div/div/div[2]/a/h4/text()[contains(., " ’ + firstName + ’ " ) and contains(.," ’ + lastName + ’ ")]’)

/parent can’t be added at the end like that the IDE throws an x on that line stating the /parent:: portion is wrong because it’s outside the xpath quote. Unless i move the /parent inside the ’ like so:

selectNameObj.addProperty(“xpath”, ConditionType.EQUALS, ‘//*[@id=“search_results_container”]/div/div/div/div[2]/a/h4/text()[contains(., " ’ + firstName + ’ " ) and contains(.," ’ + lastName + ’ ")]/parrent::h4’)

I’m wondering if we need to put the xpath into a variable and then pass the variable over to the ConditionType, i noticed in some searching no one had the xpath directly after, they all had it in a variable but not sure if that helps in anyway outside of making it than a single variable or how it all works.

I do know text is the biggest thing i need for my website and if Katalon can’t search text that is going to be a major issue. I took a screencap of the code so you could see how the IDE colors it in case something might be off. Like the word “and” counts as a word it seems instead of a keyword, but i’m unsure if that’s normal since we are encapsulating the entire xpath.

Current error: This error is same if /parent::h4 is added into the code like above.

04-10-2019 11:49:46 AM Test Cases/Create WOs

Elapsed time: 1m - 45.639s

Test Cases/Create WOs FAILED.
Reason:
com.kms.katalon.core.exception.StepFailedException: com.kms.katalon.core.webui.exception.WebElementNotFoundException: Web element with id: ‘objectName’ located by ‘By.xpath: //*[@id=“search_results_container”]/div/div/div/div[2]/a/h4/text()[contains(., “Bruce” ) and contains(.,“Willis”)]’ not found
at com.kms.katalon.core.keyword.internal.KeywordMain.stepFailed(KeywordMain.groovy:32)

Lets see if i have a link for what i was looking off of last night: addProperty('xpath' ...) with String as xpath?

This one is doing some stuff diff than what I need, but it seems they are passing the xpath to a variable with variables being passed as well. I’m not sure if the detail2 and attribute is moved over.

Specifically i’m looking part way down at this chunk of code:

//TestObject to = findTestObject(‘bm/color/colorname’)
//String prop = “//*[@class = '”+detail2+"’]//h4[contains(text(),’"+attribute+"’)]"
//to.addProperty(‘xpath’, ConditionType.EQUALS, prop, true)

Thanks again for sticking around B_L and trying to help me solve this bugger. Once we can get this text thing sorted i should be zipping along as it all depends on reading text, once that hurdle is out of the way i’m sure i’ll find a new one but that seems to be the big one for this test case.

Not a problem…hmmm

I wish I had access to the page in question…

Since I don’t let me write you code for another page and see if this helps or not for you. You can create a new test and copy and paste this and run it, it uses wikipedia.

Please note the following:

  • typically you’d create objects in the repo unless you want them dynamic (I’m sure you know this I’m just letting you know so do I :smiley:
  • I put the variables at the top so you can play with them
  • I am using the two variables to create the object I am looking for
  • I can not only see the object is present but I can capture the text and compare if I like
import com.kms.katalon.core.model.FailureHandling
import com.kms.katalon.core.testobject.ConditionType
import com.kms.katalon.core.testobject.TestObject as TestObject
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI


String variable1 = 'Automation'
String variable2 = 'ranging'

WebUI.openBrowser('https://www.wikipedia.org/')

TestObject searchObj = new TestObject("objectName")
searchObj.addProperty("xpath", ConditionType.EQUALS, '//*[@id="searchInput"]')

TestObject searchButtonObj = new TestObject("objectName")
searchButtonObj.addProperty("xpath", ConditionType.EQUALS, '//*[@id="search-form"]/fieldset/button')

WebUI.setText(searchObj, 'automation', FailureHandling.CONTINUE_ON_FAILURE)
WebUI.click(searchButtonObj)

TestObject exampleObject = new TestObject("objectName")
exampleObject.addProperty("xpath", ConditionType.EQUALS, '//*[@id="mw-content-text"]/div/p/text()[contains(., "' + variable1 +'" ) and contains(.,"' + variable2 + '")]/parent::p')


WebUI.verifyElementPresent(exampleObject, 0, FailureHandling.CONTINUE_ON_FAILURE)

String textExample = WebUI.getText(exampleObject, FailureHandling.CONTINUE_ON_FAILURE)

WebUI.comment(textExample)

WebUI.verifyMatch(textExample, 'Automation covers applications ranging from a household thermostat controlling a boiler, to a large industrial control system with tens of thousands of input measurements and output control signals. In control complexity it can range from simple on-off control to multi-variable high level algorithms.', false, FailureHandling.CONTINUE_ON_FAILURE)

WebUI.closeBrowser()

1 Like

I wonder if it’s somthing wrong with my code then, i copy pasted the portion after ConditionType.EQUALS into chrome and rmoved the + symbols and it found it with no issue (i also had no parent portion on it). But in code it fails instantly.

Mind checking my code out? I looked over your new code and based on it mine should work unless i am missing something. I’ve changed my company name to GOOGLE but that’s just my site’s name.

import static com.kms.katalon.core.checkpoint.CheckpointFactory.findCheckpoint
import static com.kms.katalon.core.testcase.TestCaseFactory.findTestCase
import static com.kms.katalon.core.testdata.TestDataFactory.findTestData
import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject
import com.kms.katalon.core.testobject.ConditionType
import com.kms.katalon.core.checkpoint.Checkpoint as Checkpoint
import com.kms.katalon.core.cucumber.keyword.CucumberBuiltinKeywords as CucumberKW
import com.kms.katalon.core.mobile.keyword.MobileBuiltInKeywords as Mobile
import com.kms.katalon.core.model.FailureHandling as FailureHandling
import com.kms.katalon.core.testcase.TestCase as TestCase
import com.kms.katalon.core.testdata.TestData as TestData
import com.kms.katalon.core.testobject.TestObject as TestObject
import com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WS
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
import internal.GlobalVariable as GlobalVariable

//Load Data
TestData searchData = findTestData(‘Data Files/WO_Object_Search’)

//Variable initialization
firstName = searchData.internallyGetValue(‘firstName’, 1)

lastName = searchData.internallyGetValue(‘lastName’, 1)

TestObject selectNameObj = new TestObject(“objectName”)

WebUI.openBrowser(’’)

WebUI.navigateToUrl(‘https://GOOGLE/login’)

WebUI.setText(findTestObject(‘Page_GOOGLE/input_Sorry something went wro’), ‘testerson@gmail.com’)

WebUI.setEncryptedText(findTestObject(‘Object Repository/Page_GOOGLE/Page_GOOGLE/input_Sorry something went wro_13’), ‘jpVOVreP5/kwzPSd8d4yQw==’)

WebUI.click(findTestObject(‘Object Repository/Page_GOOGLE/Page_GOOGLE/input_Sorry something went wro_14’))

WebUI.click(findTestObject(‘Object Repository/Page_GOOGLE/Page_GOOGLE - Service/div_concat(id( beamerOverlay’))

for (def index : (0…searchData.getRowNumbers() - 1)) {
firstName = searchData.internallyGetValue(‘firstName’, index)

lastName = searchData.internallyGetValue('lastName', index)


WebUI.click(findTestObject('Object Repository/Page_GOOGLE/Page_GOOGLE - Service/a_New'))

WebUI.setText(findTestObject('Object Repository/Page_GOOGLE/Page_GOOGLE - Service/input_HERE_job-wizard-search-b'), 
    (firstName + ' ') + lastName)

selectNameObj.addProperty("xpath", ConditionType.EQUALS, '//*[@id="search_results_container"]/div/div/div/div[2]/a/h4/text()[contains(., "' + firstName + '" ) and contains(.,"' + lastName + '")]')

if (WebUI.verifyElementPresent(selectNameObj, 0, FailureHandling.CONTINUE_ON_FAILURE)){
WebUI.click(selectNameObj)
}else{
WebUI.comment(selectNameObj + “Not Found”)
}

WebUI.click(findTestObject('Object Repository/Page_GOOGLE/Page_GOOGLE - Service/h4_Impossible Grandam'))

WebUI.setText(findTestObject('Object Repository/Page_GOOGLE/Page_GOOGLE - Service/input_WO  (Recommended)_ro-num'), 
    '640')

WebUI.setText(findTestObject('Object Repository/Page_GOOGLE/Page_GOOGLE - Service/textarea_Overview_form-control'), 
    'Overview bos')

WebUI.click(findTestObject('Object Repository/Page_GOOGLE/Page_GOOGLE - Service/label'))

WebUI.setText(findTestObject('Object Repository/Page_GOOGLE/Page_GOOGLE - Service/input_Hours  Miles_mileage'), '6700')

WebUI.selectOptionByValue(findTestObject('Page_GOOGLE/Page_GOOGLE - Service/select_Select a Technician'), 'object:530', 
    true)

WebUI.setText(findTestObject('Object Repository/Page_GOOGLE/Page_GOOGLE - Service/input_Loaner Equipment _loaner'), 
    '2')

WebUI.click(findTestObject('Object Repository/Page_GOOGLE/Page_GOOGLE - Service/label_Credit'))

WebUI.click(findTestObject('Object Repository/Page_GOOGLE/Page_GOOGLE - Service/label_Text'))

WebUI.click(findTestObject('Object Repository/Page_GOOGLE/Page_GOOGLE - Service/input_Phone_btn btn-success bt'))

WebUI.click(findTestObject('Object Repository/Page_GOOGLE/Page_GOOGLE - Service/button_Close'))

WebUI.click(findTestObject('Object Repository/Page_GOOGLE/Page_GOOGLE - Service/a_Work Orders'))

}

WebUI.closeBrowser()

hmmmm

try this

firstName = searchData.internallyGetValue(‘firstName’, 1)
WebUI.comment(firstName)

What do you get? are you getting just the name or the name with ‘’ around it?

If you do get name like Bruce showing like 'Bruce" you will need to not have the ‘’

Maybe attempt


firstName = searchData.internallyGetValue(1, 1)

Or whatever column number it is for firstName?

Additionally the text in an element is not the element and the testObject needs to be an element. I’d would try both with changing the getvalue as well as with the parent back on.

Also to rule out the problem with setting the variable, try to hardcode an xpath for one you know is on the page. See if it finds that. If it does then we know it’s the variable and how it’s being pulled.

//selectNameObj.addProperty("xpath", ConditionType.EQUALS, '//*[@id="search_results_container"]/div/div/div/div[2]/a/h4/text()[contains(., "' + firstName + '" ) and contains(.,"' + lastName + '")]')
selectNameObj.addProperty("xpath", ConditionType.EQUALS, '//*[@id="search_results_container"]/div/div/div/div[2]/a/h4/text()[contains(., "Bruce" ) and contains(.,"Willis")]')

note I added // to comment out the line so you don’t lose it. finding that though as above or as I’m fairly certain you’ll need:

//selectNameObj.addProperty("xpath", ConditionType.EQUALS, '//*[@id="search_results_container"]/div/div/div/div[2]/a/h4/text()[contains(., "' + firstName + '" ) and contains(.,"' + lastName + '")]')
selectNameObj.addProperty("xpath", ConditionType.EQUALS, '//*[@id="search_results_container"]/div/div/div/div[2]/a/h4/text()[contains(., "Bruce" ) and contains(.,"Willis")]')/parent::h4

If it is a problem with the variable and we verify the xpath is working then we can refocus on that.

another option is removing the ’ if they appear when you comment out the first name like this:

firstName = searchData.internallyGetValue(‘firstName’, 1)
firstName = firstName .replaceAll("'", "")

lastName = searchData.internallyGetValue(‘lastName’, 1)
lastName = lastName .replaceAll("'", "")

You could also trying adding in a delay

WebUI.delay(1)
``
After you navigate to the page. katalon is fast and might not be enough time for the page to load before you look for it.
1 Like

EDIT: Quick note, i have katalon set to a default delay of 2 seconds between every action taken. I don’t have delays in my code because of that predefined delay of 2 seconds.

So the name i use is actually the header title as i’m using the first row as a header, meaning Katalon can scan the document and look for the first row of data as a header and i can point to that column firstName is column 1, while lastName is column 2, the index is the row reading down the data i’ve provided after the initial header row. That isn’t the issue, that’s how katalon reads from a file. We can see it grabbed the data because the error has both names.

As to the question of keeping the ’ or not, it does not, it takes the firstName column (they are named same as my variables) and index the first row, which gets me Princess, it removes the ’ as that’s just how katalon is pointing to the header by placing ‘headerName’ like so. We could have the headers named First Name, and it would just look like ‘First Name’ for that code portion and pass it to firstName the variable.

Adding:

WebUI.comment(firstName)

Prints the first name correctly, and i added it right under the first name value i have setup: Last name will also show up correctly.

for (def index : (0…searchData.getRowNumbers() - 1)) {
firstName = searchData.internallyGetValue(‘firstName’, index)
WebUI.comment(firstName)

lastName = searchData.internallyGetValue('lastName', index)

Additionally the text in an element is not the element and the testObject needs to be an element.

What does this mean? I was going to ask if testObject is supposed to be something i identify, stupid question i’m sure. I’m not sure what the testObject is, outside of trying to find this xpath. Some of the code is a mix of your original and newer stuff.

The error does show: "Web element with id: ‘objectName’ " so maybe i am not using objectName correctly?

This does seem to indicate the xpath is somehow messing up or maybe it’s the if statement to click the element.

That was your early post, maybe this isn’t how to handle it? Then again maybe it is my lack of understanding the objectName.

if (WebUI.verifyElementPresent(selectNameObj, 0, FailureHandling.CONTINUE_ON_FAILURE)){
WebUI.click(selectNameObj)
}else{
WebUI.comment(selectNameObj + “Not Found”)
}

Final note it won’t work with just proper names either instead of variables… Now that you have mentioned the objectName not being right, i feel that could be the issue. I am just unsure how to change it or what it means by object name, is this like the id a path or what? I almost asked last time about this variable, but i chickened out. If it’s a place holder i actually ahve it written as objectName for this line

TestObject selectNameObj = new TestObject(“objectName”)

If objectName needs to be something let me know so i can do that up, that’d be funny and sad if that was the issue.

Just got word from our devs when looking at this idea that i’m stupid and objectName was supposed to be something, i asked a dev what our buttons are, and they said they use anchor tags as the clickable space so he said < a > is our button…

So would objectName be < a > or even a?

EDIT Adding spaces to make those show up but minus those spaces is what he says our anchor tags are.

Good news!

This:

selectNameObj.addProperty(“xpath”, ConditionType.EQUALS, ‘//*[@id=“search_results_container”]/div/div/div/div[2]/a/h4/text()[contains(., "’ + firstName + ‘" ) and contains(.,"’ + lastName + ‘")]/parent::h4’)

Works, though i swear we tried this earlier. When you said parent::a i tried parent::h4 too as i think you might have mentioned that as well, or i noticed that was the area… Now i’m wondering what out of no where would cause it to work.

So, it’s working, i just changed the sort order in my excel document and it read it correctly and went to the next stage which is oddly enough another read excel and click correctly… so, i guess time to apply knoweldge and see if it works…!

Thanks D_L for working through this problem with me, and giving me a ton of help, and things to work with.