Let’s look at the square with thick black border positioned from the top underneath first row of white rectangles, the big red one. This was a bit slow and we are happy for the red colour, otherwise it would have been even slower. This is one way of writing a CSS selector, based on the elements that hold it.

Another way is if we put a number in each square, from the upper left corner to the upper right corner. Now we can say that we talk about the square number 5. This was way faster. This called an “id”. Each “id” must be unique, else we ruin all the speed and idea. An HTML tag can have 1 id.

Let’s try to locate the element which has “square black”. It went quite as fast as the “id”, maybe a bit slower, but still way faster then the first solution. This is called a class. An html tag can have any number of classes. The more they are the slower it becomes to knowing which one we select.

Adding a style to an element:

We have seen how selecting elements work, which is the fastest and which is the slowest. Let’s imagine how paining would work if we imagine ourselves as browsers. We will ignore the first try of selection because it is plain stupid to work like that.

Apply a border to the tags with id 1,2,3,4,5,6,7,8,9…19,20. This looks quite slow because you always have to go back and see if the tag with a specific “id” needs to have the border painted or not.

Apply the border to all the tags with class “black”. Hm…. this looks super fast if you already have all the tags split in piles. All the ones with “black” in the “black” pile. All the “squares” in their own pile and all the “rectangles” in the “rectangles” one.

This is how the browser finds tags and paints tags. We can easily see why the “id” is faster to find and why the “class” is faster to paint.

Next time we will add some colour to our small piece of HTML from the previous lessons.

Before we start, thank you Mario for listening to my idea and coming up with a better one :).

Last night I have finished implementing a feature into Behat on which I have mixed feelings about. It allows the team to store the selectors in an external file. Now, this sounded great at first and I did not vouch against. Mostly I was curios how it can be done.

I am saying it is a bad idea because sending parameters to the FeatureContext constructor can be done through several different ways:

– an array of parameters via the behat.yml that can be extended through import to include a different file

– a multi-dimensional array via the Scenario Outline and the Examples table

– a normal file include in FeatureContext

However, none of those actually inserts the values into the scenarios at runtime, replacing the keywords. This is when I get to say that it is genius.

But again, this should not be used in the first place. The whole purpose of BDD (in this context) is to be a tool that provides documentation for the stakeholders replacing a tests managements tool. Else we should not have used Gerkin to begin with. But what if the the target is the QA person, if so it makes sense. However, we are testing a framework built on top of Magento that we implement for the clients. Now it gets back to be a bad idea. The clients will not understand jack from our tests. On the other hand, since we share some of the code base but we implement custom functionalities on top of it, we want to maintain or selectors and values in a decoupled spot and not work on the code all the time. But the .feature files are quite decoupled as they are. Uhmm… reasons reasons.

I will let you reader to meditate upon using it or not and if you do use the code, please drop a comment why. Thank you in advance unknown friend.

We will start with a top down overview of the implementation. The xxxx.feature file looks like this:

1234567891011

Scenario Outline: Invalid user login
Given I am on homepage
And I follow "Log In"
And I fill in "email" with "<__email__>"
And I fill in "pass" with "<__password__>"
And I press "<__button__>"
Then I should see "<__messageBody__>"

Examples:
| |
| |

The current implementation needs to have the empty table at the end in order for Behat to generate an array at runtime. Probably this can be fixed in the code. The <> are regular placeholders. They are substitute with the values from the Examples table at runtime. The “__” (double underscore) are used in order to ensure some kind of differentiation between our keys and the table already existing.

In FeatureContext.php I have created this method that will be loaded on the @BeforeFeature hook:

The class for this is a file called ExamplesLoader.php, located in the Bootstrap folder. This does not have to be loaded or anything because Behat automatically loads all the classes from that folder. Since the logic is in here I will post it based on functionality.

This will iterate through our scenarios and for each scenario will get the examples. In will return an array with the number of elements equal to the number of rows in the Examples table. In the current implementation it works with two.

1234

foreach($feature->getScenarios()as$scenario){$examples=$scenario->getExamples();// all the other pieces of code will go in here. Leave it blank.}

This piece will glue together the current working directory ( getcwd() and the name of the file where the selectors/locators exist ). They will be glued by the DIRECTORY_SEPARATOR so it works on every operating system. Please note that the working directory is where behat.yml is located, not where the current file exists. This string will exist in the “$filePath” variable.
The “$holder” will contain a bi-dimensional read from the “tsv” file just read. If you want to read a file with a different separator please read the PHP documentation for fgetcsv(). The second argument is the separator. Also, if the examples table is longer an iteration inside the $holder[$row] is required because we want to have data for all the rows, not just two.

123456789101112

$filePath=join(DIRECTORY_SEPARATOR,array(getcwd(),'locatorsFile.tsv'));$holder=array();$row=0;if(($handle=fopen($filePath,"r"))!==FALSE){while(($data=fgetcsv($handle,1000,"\t"))!==FALSE){//if you are thinking that it would be better to iterate over many elements,//don't later you will use only key:value$holder[$row]=array($data[0],$data[1]);$row++;}fclose($handle);}

The $rows is a variable created by Behat which stores all the values of the Examples table. Each element of this array is an array of what is inside between 2x| (pipe) on that specific row in examples. Basically here is where we want to add our keys and values. Because after we are inserting them, the framework will handle all the logic that there is to come. The setRows($rows) is a method that locks in place this table for tests creation.

1234567

// Add our global examplesforeach($holderas$value){$rows[0][]=$value[0];$rows[1][]=$value[1];}//and we send the data to the examples table$examples->setRows($rows);

Now our table will include all the data from locatorsFile.tsv. Here’s how that file looks like on the inside: