Selenium : The hell of Angular

Recently have some trouble automating an Application using Angular using Selenium and SerenityBDD.

I found a component that helps a lot. NGWebDriver

How to search an element and interact with it?

import com.paulhammant.ngwebdriver.ByAngularCssContainingText;

waitFor(ExpectedConditions.visibilityOfElementLocated(By.xpath("//my-form[@class='myclass']")));
find(ByAngularCssContainingText.xpath(//my-form[@class='myclass'])).click();

Also it could be handy to sometime wait that Angular load everything by using:

waitForAngularRequestsToFinish();

Also I had to revise a bit my Xpath way of working. Here is a good tutorial :  https://www.guru99.com/xpath-selenium.html

Jmeter

Here some note I took while exploring Jmeter.

Pre-requirement

  • jmeter 5.0
  • Ensure to have added in PATH the location of the bin folder of jmeter
  •  jre 1.8

How to start Jmeter GUI

  • Go where you have downloaded the binaries then run `jmeter.bat` using command line. Or type jmeter.bat if you have the bin folder of jmeter in the PATH.
  • Do not run performance test with GUI. Only for design and debugging purpose with low charge.

How to run Jmeter in command line

  • jmeter -n -e -l appLog.csv -o appReport -t app.jmx
    • `-n` to run in cli mode
    • `-e` to create a report at the end of the run. It requires `-l`
    • `-l` log file name and path
    • `-t` testplan file and path
    • `-o` path where the report is generated

Record script

  • Use the HTTP(S) test Script Recorder with the port 8000
    • On the Root > Add > Non-Test Elements > HTTP(S) test Script Recorder
  • Use firefox and setup the proxy to 8000
  • Record under the current : “HTTP(S) test Script Recorder” then copy the step in each “Recording Controller”
    • On a Thread Group > Add > Logic Controller > Recording Controller
  • Record each step with a different label
    • HTTP Sample settings : Prefix
    • Update each step with a meaning step name
    • Avoid to “Retrive All Embedded Ressources” to keep it simple.
    • Avoid “Redirect Automatically”
    • Allow “Follow Redirects”
    • Alkow “Use KeepAlive”

Thread Group structure

  • “HTTP Request Defaults” : to setup the default root url
    • On a Thread Group > Add > Config Elements > HTTP Request Defaults
  • “HTTP Cookie Manager” : to handle the cookie reset at each iteration
    • On a Thread Group > Add > Config Elements > HTTP Cookie Manager
  • “User Parameters” : to handle the variables and users
    • On a Thread Group > Add > Pro Processors > User Parameters
  • “Debug Sampler” : to retrieve all the variables for debug purpose
    • On a Thread Group > Add > Sampler > User Parameters
  • “View Results Tree” : to see all the step details
    • On a Thread Group > Add > Listener > View Results Tree
  • “Summary Report” : to see the metrics
    • On a Thread Group > Add > Listener > Summary Report

To catch value in response

  • Use Json Extractor : It allow to get a value in json by using JSON Path expression and assign to an existing (JMeter Variable Name to use) or new variables (Names of created variables) with n variables separated by coma.
    • On the http request > Add > Pro Processors > Json Extractor

Other references

  • master/slave architecture for distributed testing : https://jmeter.apache.org/usermanual/jmeter_distributed_testing_step_by_step.pdf

Selenium : How to use Javascript to show button or move a window.

I had some trouble lately with some Angular interface. So here  interesting work around I found.

Scenario 1 : You have  a list of checkbox to click, they are not hidden but hidden under an other element. Like hidden behind a pop-up window or a menu button, but they should partially visible for a human user.
The work around : move the checkbox to a visible position in the page. How?

JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].scrollIntoView(true);", checkBoxElement);

Scenario 2 : You want to move a Pop-up window using Javascript by using the position.

JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].setAttribute('style', 'top: 0px');", windowElement);