Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.openqa.selenium.*;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.Select;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testcontainers.Testcontainers;

Expand Down Expand Up @@ -127,6 +128,29 @@ public static void clickAndWaitPageLoad(WebDriver driver, String cssSelector){
//TODO will need to check if JS executing in background
}

public static void selectAndWaitPageLoad(WebDriver driver, String cssSelector, String value) {
Select element;
try {
WebElement el = driver.findElement(By.cssSelector(cssSelector));
element = new Select(el);
} catch (NoSuchElementException e) {
throw new RuntimeException("Cannot locate element with '" + cssSelector + "'." +
"\nCurrent URL is: " + driver.getCurrentUrl() +
"\nCurrent page is: " + driver.getPageSource());
}
try {
element.selectByValue(value);
} catch (NoSuchElementException e){
element.selectByVisibleText(value);
}

try {
Thread.sleep(50);
} catch (Exception e) {
}
waitForPageToLoad(driver, 2);
}

public static void goToPage(WebDriver driver, String pageURL, int timeoutSeconds){
driver.get(pageURL);
waitForPageToLoad(driver, timeoutSeconds);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
@JvmStatic
@BeforeAll
fun beforeAll(): Unit {
browser.startChromeInDocker()

Check failure on line 22 in core-it/src/test/kotlin/org/evomaster/core/problem/webfrontend/service/BrowserControllerDockerTest.kt

View workflow job for this annotation

GitHub Actions / JUnit Test Report

BrowserControllerDockerTest.

Container startup failed for image selenium/standalone-chrome:4.11.0
Raw output
org.testcontainers.containers.ContainerLaunchException: Container startup failed for image selenium/standalone-chrome:4.11.0
	at org.testcontainers.containers.GenericContainer.doStart(GenericContainer.java:351)
	at org.testcontainers.containers.GenericContainer.start(GenericContainer.java:322)
	at org.evomaster.core.problem.webfrontend.service.BrowserController.startChromeInDocker(BrowserController.kt:37)
	at org.evomaster.core.problem.webfrontend.service.BrowserControllerDockerTest$Companion.beforeAll(BrowserControllerDockerTest.kt:22)
	at org.evomaster.core.problem.webfrontend.service.BrowserControllerDockerTest.beforeAll(BrowserControllerDockerTest.kt)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
	at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptLifecycleMethod(TimeoutExtension.java:126)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptBeforeAllMethod(TimeoutExtension.java:68)
	at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeBeforeAllMethods$9(ClassBasedTestDescriptor.java:384)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeBeforeAllMethods(ClassBasedTestDescriptor.java:382)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:196)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:78)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:136)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
	at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService$ExclusiveTask.compute(ForkJoinPoolHierarchicalTestExecutorService.java:185)
	at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService.executeNonConcurrentTasks(ForkJoinPoolHierarchicalTestExecutorService.java:155)
	at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService.invokeAll(ForkJoinPoolHierarchicalTestExecutorService.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
	at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService$ExclusiveTask.compute(ForkJoinPoolHierarchicalTestExecutorService.java:185)
	at java.util.concurrent.RecursiveAction.exec(RecursiveAction.java:189)
	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
	at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
	at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
	at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:175)
Caused by: org.rnorth.ducttape.RetryCountExceededException: Retry limit hit with exception
	at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:88)
	at org.testcontainers.containers.GenericContainer.doStart(GenericContainer.java:336)
	... 52 more
Caused by: org.testcontainers.containers.ContainerLaunchException: Could not create/start container
	at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:556)
	at org.testcontainers.containers.GenericContainer.lambda$doStart$0(GenericContainer.java:346)
	at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:81)
	... 53 more
Caused by: com.github.dockerjava.api.exception.BadRequestException: Status 400: {"message":"Duplicate mount point: /dev/shm"}

	at org.testcontainers.shaded.com.github.dockerjava.core.DefaultInvocationBuilder.execute(DefaultInvocationBuilder.java:237)
	at org.testcontainers.shaded.com.github.dockerjava.core.DefaultInvocationBuilder.post(DefaultInvocationBuilder.java:124)
	at org.testcontainers.shaded.com.github.dockerjava.core.exec.CreateContainerCmdExec.execute(CreateContainerCmdExec.java:37)
	at org.testcontainers.shaded.com.github.dockerjava.core.exec.CreateContainerCmdExec.execute(CreateContainerCmdExec.java:13)
	at org.testcontainers.shaded.com.github.dockerjava.core.exec.AbstrSyncDockerCmdExec.exec(AbstrSyncDockerCmdExec.java:21)
	at org.testcontainers.shaded.com.github.dockerjava.core.command.AbstrDockerCmd.exec(AbstrDockerCmd.java:33)
	at org.testcontainers.shaded.com.github.dockerjava.core.command.CreateContainerCmdImpl.exec(CreateContainerCmdImpl.java:608)
	at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:430)
	... 55 more
}

@JvmStatic
Expand Down Expand Up @@ -83,4 +83,49 @@
browser.goBack()
assertEquals(aPage, browser.getCurrentUrl())
}

//TODO @IVa add test for Select
@Test
fun testSingleSelect(){
browser.initUrlOfStartingPage("http://localhost:8080/",true)
//browser.initUrlOfStartingPage("http://localhost:${getPort()}",true)// to double check
browser.goToStartingPage()

var actions = browser.computePossibleUserInteractions()
assertEquals(1, actions.size)

Check failure on line 95 in core-it/src/test/kotlin/org/evomaster/core/problem/webfrontend/service/BrowserControllerDockerTest.kt

View workflow job for this annotation

GitHub Actions / JUnit Test Report

BrowserControllerDockerTest.testSingleSelect

expected: <1> but was: <5>
Raw output
org.opentest4j.AssertionFailedError: expected: <1> but was: <5>
	at org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55)
	at org.junit.jupiter.api.AssertionUtils.failNotEqual(AssertionUtils.java:62)
	at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:150)
	at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:145)
	at org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:510)
	at org.evomaster.core.problem.webfrontend.service.BrowserControllerDockerTest.testSingleSelect(BrowserControllerDockerTest.kt:95)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
	at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
	at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:210)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:206)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:131)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
	at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService$ExclusiveTask.compute(ForkJoinPoolHierarchicalTestExecutorService.java:185)
	at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService.executeNonConcurrentTasks(ForkJoinPoolHierarchicalTestExecutorService.java:155)
	at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService.invokeAll(ForkJoinPoolHierarchicalTestExecutorService.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
	at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService$ExclusiveTask.compute(ForkJoinPoolHierarchicalTestExecutorService.java:185)
	at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService.executeNonConcurrentTasks(ForkJoinPoolHierarchicalTestExecutorService.java:155)
	at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService.invokeAll(ForkJoinPoolHierarchicalTestExecutorService.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
	at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService$ExclusiveTask.compute(ForkJoinPoolHierarchicalTestExecutorService.java:185)
	at java.util.concurrent.RecursiveAction.exec(RecursiveAction.java:189)
	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
	at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
	at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
	at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:175)
val homePage = browser.getCurrentUrl()
assertTrue(homePage.endsWith("/"), homePage)
val a = actions[0] // first action is the dropdown list
assertEquals(UserActionType.SELECT_SINGLE, a.userActionType)

browser.selectAndWaitPageLoad(a.cssSelector, listOf(a.inputs[1].toString()))
val page1 = browser.getCurrentUrl()
assertTrue(page1.endsWith("1?"), page1)// ? to be fixed

actions = browser.computePossibleUserInteractions()
assertEquals(1, actions.size)
var backHome = actions.first { it.cssSelector.contains("a") }
browser.clickAndWaitPageLoad(backHome.cssSelector)
assertEquals(homePage, browser.getCurrentUrl())

browser.selectAndWaitPageLoad(a.cssSelector, listOf(a.inputs[2].toString()))
val page2 = browser.getCurrentUrl()
assertTrue(page2.endsWith("2?"), page2)
actions = browser.computePossibleUserInteractions()
assertEquals(1, actions.size)
backHome = actions.first { it.cssSelector.contains("a") }
browser.clickAndWaitPageLoad(backHome.cssSelector)
assertEquals(homePage, browser.getCurrentUrl())

browser.selectAndWaitPageLoad(a.cssSelector, listOf(a.inputs[3].toString()))
val page3 = browser.getCurrentUrl()
assertTrue(page3.endsWith("3?"), page3)
actions = browser.computePossibleUserInteractions()
assertEquals(1, actions.size)
backHome = actions.first { it.cssSelector.contains("a") }
browser.clickAndWaitPageLoad(backHome.cssSelector)
assertEquals(homePage, browser.getCurrentUrl())

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ class WebTestCaseWriter : TestCaseWriter() {
lines.addStatement("goToPage($driver, $baseUrlOfSut, 5)")

if(ind.individual is WebIndividual){
ind.evaluatedMainActions().forEachIndexed { index, a ->
val all = ind.evaluatedMainActions()
for(index in all.indices) {
val a = all[index]
if(a.result.stopping){
break
}
addActionLines(a.action, index, testCaseName, lines, a.result, testSuitePath, baseUrlOfSut)
}
val lastEvaluated = ind.evaluatedMainActions().last()
Expand All @@ -44,8 +49,10 @@ class WebTestCaseWriter : TestCaseWriter() {
lastResult.getUrlPageEnd()!!
} else {
//if stopping, it means nothing could be done, and no info on where it went.
//it also implies that such entry itself was printed out in the test
assert(lastAction.userInteractions.isEmpty())
//it also implies that such entry itself was printed out in the test.
//however, it might be that a mutated test ends up on a page in which action is not applicable
//TODO should check lastAction.isApplicableInGivenPage(pageBeforeExecutingAction)
//assert(lastAction.userInteractions.isEmpty())
lastResult.getUrlPageStart()!!
}
lines.add(getCommentOnPage("ended on page", url,null,lastResult.getValidHtml()))
Expand Down Expand Up @@ -77,6 +84,11 @@ class WebTestCaseWriter : TestCaseWriter() {
lines.addStatement("clickAndWaitPageLoad($driver, \"${it.cssSelector}\")")
lines.append(getCommentOnPage("on page", r.getUrlPageStart()!!, r.getUrlPageEnd(), r.getValidHtml()))
}
UserActionType.SELECT_SINGLE-> {
val selectedValue = a.singleSelection[it.cssSelector]?.getValueAsRawString() // TODO what if missing?
lines.addStatement("selectAndWaitPageLoad($driver, \"${it.cssSelector}\", \"$selectedValue\")")
lines.append(getCommentOnPage("on page", r.getUrlPageStart()!!, r.getUrlPageEnd(), r.getValidHtml()))
}
//TODO all other cases
else -> throw IllegalStateException("Not handled action type: ${it.userActionType}")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
package org.evomaster.core.problem.webfrontend

import org.evomaster.core.search.gene.collection.EnumGene
import org.evomaster.core.search.gene.numeric.IntegerGene
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.openqa.selenium.By
import org.openqa.selenium.remote.RemoteWebDriver
import org.openqa.selenium.support.ui.Select
import java.net.URI
import java.net.URISyntaxException
import java.net.URL
import kotlin.math.min

object BrowserActionBuilder {


fun computePossibleUserInteractions(html: String) : List<WebUserInteraction>{
/**
* Given the current page we need to see what can we do in the page, what kind of interactions we can have.
*/
fun computePossibleUserInteractions(driver: RemoteWebDriver) : List<WebUserInteraction>{


val document = try{
Jsoup.parse(html)
Jsoup.parse(driver.pageSource)
}catch (e: Exception){
//TODO double-check
return listOf()
Expand All @@ -22,10 +31,52 @@ object BrowserActionBuilder {

//TODO all cases

handleALinks(document, driver, list)
handleDropDowns(document, driver, list)

return list
}

private fun handleDropDowns(
document: Document,
driver: RemoteWebDriver,
list: MutableList<WebUserInteraction>
) {

document.getElementsByTag("select")
.forEach { jsoup ->
val dropdown = Select(driver.findElement(By.cssSelector(jsoup.cssSelector())))
val type = if(dropdown.isMultiple) {
UserActionType.SELECT_MULTI
} else {
UserActionType.SELECT_SINGLE
}
val options = dropdown.options
.filter{it.isEnabled}
.map{
/*
Look at "value" attribute. unfortunately, it is not mandatory.
in such case, we rather use the visible text.
note: prefer avoiding indices, as they are not reliable, eg, if changes, it would not
break the test, unless out of bounds
*/
it.getAttribute("value") ?: it.text
}
list.add(WebUserInteraction(jsoup.cssSelector(), type, options))
}
}


/* Analyze anchor tags to identify clickable elements*/
private fun handleALinks(
document: Document,
driver: RemoteWebDriver,
list: MutableList<WebUserInteraction>
) {
document.getElementsByTag("a")
.forEach {
val href = it.attr("href")
val canClick = if(!href.isNullOrBlank()) {
val canClick = if (!href.isNullOrBlank()) {
val uri = try {
URI(href)
} catch (e: URISyntaxException) {
Expand All @@ -38,25 +89,36 @@ object BrowserActionBuilder {
val onclick = it.attr("onclick")
!onclick.isNullOrBlank()
}
if(canClick){
if (canClick) {
list.add(WebUserInteraction(it.cssSelector(), UserActionType.CLICK))
}
}

return list
}


fun createPossibleActions(html: String) : List<WebAction>{
fun createPossibleActions(driver: RemoteWebDriver) : List<WebAction>{

val interactions = computePossibleUserInteractions(html)
val interactions = computePossibleUserInteractions(driver)

val inputs = interactions.filter { it.userActionType == UserActionType.FILL_TEXT }
val others = interactions.filter { it.userActionType != UserActionType.FILL_TEXT }

//TODO genes for inputs

return others.map { WebAction(mutableListOf(it)) }
return others.map {
when(it.userActionType) {
UserActionType.CLICK -> WebAction(mutableListOf(it))
UserActionType.SELECT_SINGLE -> {
val selection = EnumGene<String>(it.cssSelector, it.inputs)
WebAction(mutableListOf(it), singleSelection = mutableMapOf(it.cssSelector to selection))
}
//TODO multi
else -> {
//TODO log warn
WebAction(mutableListOf(it))
}
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,28 @@ enum class UserActionType {

CLICK,

FILL_TEXT
FILL_TEXT,

/**
* Select only a single element in a dropdown <select> element
*/
SELECT_SINGLE,

/**
* Some dropdown <select> elements might allow to select more than one element
*/
SELECT_MULTI,

DOUBLE_CLICK,
RIGHT_CLICK,
HOVER_OVER_ELEMENT,
VERTICAL_SCROLLING,
HORIZONTAL_SCROLLING,
DRAG_AND_DROP,

CHECK_CHECKBOX,
UNCHECK_CHECKBOX,
CHOOSE_RADIO_BUTTON,
SELECT,
UPLOAD_FILE,
}
Loading
Loading