Build feeder from HTMl

Hey,

I can’t find the solution to build a feeder from the received html. I have a table with links and want to send this links to the next step (I can’t guess the links) :

question 1 question 2 question 3

I want to build a list of all this links and provide it to the next step which allow user answer this questions. I can’t build a csv file to provide this urls.

Is it possible to create a feeder from the HTML and provide it to the next step? Can you give me some advice to create it? I have no experience with scala or gatling but I can already send answer by providing the url in code (not flexible as much…)

Thanks

Not sure I understand what you attend to do.

Is your scenario looking like that ?

scenario:

  • request 1: query that URL that provides some links
  • request “question-1.html”
  • request “question-n.html”

This means that all users will go thru the scenario, so, all users will access all questions. Or, is the user1 only supposed to access question1, user2 access question2 etc ?

cheers
Nicolas

any user can access any question, randomly

Okay, I can get the first link of my list but haw can I get the whole list? I find “findAll” but don’t know how to use it…

Can you share your current code ?

import io.gatling.core.Predef._
import io.gatling.core.session.Expression
import io.gatling.core.session._
import io.gatling.http.Predef._
import io.gatling.jdbc.Predef._
import io.gatling.http.Headers.Names._
import io.gatling.http.Headers.Values._
import scala.concurrent.duration._
import bootstrap._
import assertions._
object TestScenario {

val test = exec(http(“Get question list”)
.get(“/answers”)
.check(
css(“.view-id-bonita_q_a.view-display-id-panel_pane_1 .view-content .bonita-views-qa-rows .views-field-qa-title a”, “href”).saveAs(“class”)
)
).exec(session=> {
println(session)
session
})
val scn = scenario(“Test”).exec(test)

}

I run the scenario in a simulation which inject only one user at once and run only this scenario.

So, if you change that to :
css(".view-id-bonita_q_a.view-display-id-panel_pane_1 .view-content .bonita-views-qa-rows .views-field-qa-title a", “href”).findAll.saveAs(“allLinks”)

you session should now have all links in it.

Yeah! It works!

Just a last question : I can create a random variable between 0 and allLinks.size and select the url to get in an exec section ?

And how can I exclude “/community” from the url? my baseUrl contain it (sorry, no scala knowledge…)

import scala.util.Random

.exec(session=> {
val allLinks = sessions(“allLinks”).as[List[String]].filter(!_.contains(“community”))
val nextLink = allLinks(Random.nextInt(allLinks.length))
session.set(“nextLink”, nextLink)
})

Is that working for you ?

Nicolas

No : scala.collection.mutable.ArrayBuffer cannot be cast to scala.collection.immutable.List

Sorry, this way then :

import scala.collection.mutable.ArrayBuffer

val allLinks = sessions(“allLinks”).as[ArrayBuffer[String]].filter(!_.contains(“community”))

Yes, that’s better.
The end of the line “filter[…]” select only the values which not contains “community”, I only want to exclude it from the value. Like substr($value, 0, 10) with PHP.

In Java/Scala : “nicolas”.substring(0,5)

Ok ?

PERFECT !

Thanks a lot !

Actually, Gatling EL supports a random function.

If that matches your needs, you could filter out the community links in a transform step directly in your check: https://github.com/excilys/gatling/wiki/Checks#wiki-transforming
and then use “${links.random}”

Cheers,

Stéphane

Nicolas,
I’ve actually have similar situation - some data (list of ids) is requested form a service to be used in test.

Is there a way to share this data between users? So that only one request was made to get data.

I’ve tried to store the data in a var and check if it is there so that the first user checks the var, sees its empty and requests the data and stored it. Then the second user checks the var, sees it has data and does not requests but uses it.

Can Gatling work such way or the data should be requested before the simulation starts? So far it seems that even when
e.g.
val scn = scenario(“request by id”)

.exec( doIf( data.isEmpty){ .exec(GetData) }) // Get test data

.during( duration){exec( request() ).pause(800 milliseconds, 1200 milliseconds) }

def GetData = http( “Get ids list form service”)
.get("""/idservice&limit=400""")
.headers( auth )
.check(jsonPath("$.data…id").findAll.saveAs(“ids”))

What I want to achieve is prevent all users to request data - just the first one. Is it possible?

Thanks!

Gerrald G

Gatling is not intended for this, so GetData will be counted in the stats.

Anyway, if you reaaaaaly want to go this way:

  • make you var volatile or an AtomicReference
  • data.isEmpty is static value, so it’s only evaluated once, when the simulation is loaded. try doIf(_ => data.isEmpty)

1/ “try doIf(_ => data.isEmpty)

that this point is very important.
What you wrote was: doIf(data.isEmpty)
this will simply be evaluated as doIf(false)

2/ After, you should not forget to bridge that, the link between the “user session” and the “scala context”

@volatile var data: Seq[Int] = Nil

.exec( doIfOrElse(_ => data.isEmpty){ getData } { session => session.set(“ids”, data) })

def getData =
exec(http( “Get ids list form service”)
.get("""/idservice&limit=400""")
.headers( auth )
.check(jsonPath("$.data…id").findAll.saveAs(“ids”)))
.exec(session => data=session(“ids”).as[Seq[Int]])

3/ Also, note that this code may not give you “only one request”, but one or a few.
Indeed, between the test and the set of the “data” variable, some time may be elapsed.
Is this enough of a tradeoff for you ?

cheers
Nicolas