Find The Button In The Room

Introduction

This is my second blog post in the Find In The Room blog post serie. In order to avoid any legal issues I sanitised my story. It is about software testing and IT: test automation.

For this story I will use the Cinema Hype VIP website.

Voice commercial:
“Are you tired to buy drinks and snacks for a child birthday party in a cinema?
Cinema Hype VIP website is here to rescue you.”
Author – that’s me: “Let me turn down the volume.”
[Presses a button]
Commercial [Loud voice] “Now you can order everything before setting a foot in the cinema.”
Me: “Excuse me. Let me mute the volume.”
[Presses a button]
Commercial: [Loud voice] “What are you waiting for?”

Me: [Surprised]
[Presses a button]
Commercial: [Silent]
Me: [Silently smiling]
[Presses a button]
Commercial: [Silent]
Me: “Test. 1 2 3. ”

Commercial: [Silent]
Me [Remains a few seconds silent.]
Commercial: [Silent]
Me [Looks a few lines up and down.]
Me [Remains a few seconds silent.]
Commercial: [Silent]
Me: “Ahum.”
Commercial: [Silent]
Me: “Someone is watching me from a few lines above.
Oh, I watched myself.”

The moment of approval

In my introduction I wrote several times about the button. It took me some effort to find the right button.

Now it is time for a real world test automation example. For my first big test automation experience I programmed the steps in Java. Selenium was used for the interaction with the website.

One of the most important steps of a website is pushing a button. These days a lot of deals are closed with a press of a button. Also online transactions need some key presses to pay. So I must be able to find a button on the web page.

Let me return to the Cinema hype VIP website.
My kid has a birthday party and all tickets, snacks, and drinks are listed. The only thing I have to do is to press a button.

The quickest way

Years ago I thought that there was one way to find a button.

  • Right click the button and select Inspect in the Option menu.
    An option  menu is shown above the OK button. The last menu option is Inspecteren or inspect in English!
  • Select the HTML code of the button and copy XPath.
    In DevTools  menu is shown above the HTML text for the OK button. This menu contains the sub menu Copy containing the option Copy XPath!
  • Give XPath to Selenium to find the button.
  • Pat myself on my shoulder.

Then my attention was drawn to the free online course of Andrew Knight, Web Element Locator Strategies, on Test Automation University.
So what did I actually use?

An XPath is basically a route description through the web page. And it can look a bit scary:
/html/body/div[2]/div/div[2]/button
This is of course automatically followed by Selenium. That is something programs tend to do. There is 1 huge problem. If signs change, then Selenium cannot find its way.

[Update author: my opinion is not the same as the author of the referred characters, but I believe in the goodness of the good characters.]

Let me use an arbitrary text on a letter and transform it to a more computer friendly notation.

/Surrey / Little Whinging / Privet Drive 4 / The Cupboard under the Stairs / Mr. H. Potter.

If his uncle would move Mr. Potter to a bed room, then the postman had still no problem with delivery. Same address and a decent room this time.

Would it a bit more convenient to address the letter to a mister called H. Potter? A muggle postman would have serious problems, if this Mr. is evacuated to an island before his 12th anniversary. But finding him is a Half Giant job for a bloke like Hagrid.

This would lead to:
//Mr. H. Potter

But computers need more details:
//Human[contains(text() = 'Mr. H. Potter`]

Find a button with text OK.In that case I would get something like
//button[text()='OK']

The HTML code of the OK is hightlighted, while the search bar contains the text “//button[text()='OK']” followed by the text “1 of 1”!

Let me give you a more precise translation:

  • “//” means “Find somewhere on the page”
  • “button” means “the first button you encounter”
  • “[text()= ‘OK’]” means with the condition, that the text is equal to ‘OK’

No idea

But this does not completely explain:
/html/body/div[2]/div/div[2]/button

  • “/” means “search directly under”
    “body/div” means “search the first div under the body”
  • “[2]” means the second, so
    “div[2]” is the second div.
  • The rectangular brackes, “[” and “]”, are useful, if I do not need the first , but another one in the row.

The website I was testing was created with a low code tool. This tool can be compared with an advanced presentation tool, which also builds a fully functional website.

With great power comes great creativity. This basically means, that certain things were not fully under control of the developers. As a tester I had to solve these problems.

Placing a button on a web page led to an explosion of actions. Lots of code were automatically added, but this led to names like 1_saveFiles.

So I used ‘1_saveFiles’. A fellow tester pointed out, that the low code tool could change the button name to ‘2_saveFiles’ at will.

So I focused on the last part of the string.
//Button[contains(@name, 'saveFiles')]
This means such much as
“Search a button with the name containing saveFiles”
Of course there is a faster way to address an element using the attribute id. There is no magic needed to find Mr. Potter, if we were on the same page.
//Human[contains(@id, 'Mr. H. Potter`]

By the way id is pronounced as at Eye Dee instead of it. If you want to surprise your big sister or brother test automator, then use a sentence like “That element had probably no id.” Don’t forget a little sigh.

In my case id was not always set. To make things a little more challenging for me a single condition was not enough.

This is an exaggerated situation:
Code for dirnks: <input class="radio" name="2_drink" type="radio" value="one"> Cola</label> <br> <input class="radio" name="2_drink" type="radio" value="two"> Lemonade</label> <br> <input class="radio" name="2_drink" type="radio" value="three”> Sparkling Orange</label> <br>!

//input[contains(@name, 'drink')]
This might lead to some drink

//input[@value = 'two')]
could lead to the second drink or second snack.

So I chose for two conditions:
//input[contains(@name, 'drink')][@value = 'two']

There were other cool tricks in the course of Andrew Knight. The described ones in this blog post were big time savers.

Show and fail

It was time for the demo. My team liked that I would show my scripts in action. People were looking when I kicked off the tests.

An unexpected dialog popped up. I had to close it. What went wrong?

I apologised and left the stage. My team members postponed the demonstration of my tests.

Time for another blog post.