Geb testing with select2


Found this article which led me close. The author states that both an EmptyNaviagtor and NonEmptyNavigator should be created, however since the EmptyNavigator did not add any functionality it does not need to be created.

First create NonEmptyNavigator

The navigators should be placed somewhere inside
“integration-test/groovy”. The author First create NonEmptyNavigator.groovy:

import geb.Browser
import groovy.transform.CompileDynamic
import org.openqa.selenium.WebElement

/**
 * Non empty navigator class geb
 */
@CompileDynamic
@SuppressWarnings(['ClassNameSameAsSuperclass'])
class NonEmptyNavigator extends geb.navigator.NonEmptyNavigator {

    NonEmptyNavigator(Browser browser, Collection<? extends WebElement> contextElements) {
        super(browser, contextElements)
    }

    void select(String value) {
        //browser.js.exec(firstElement(), value, 'jQuery(arguments[0]).select2("val", arguments[1]);')
        browser.js.exec(firstElement(), value, 'jQuery(arguments[0]).val(arguments[1]).trigger("change");')
    }
    String getSelectedValue() {
        browser.js.exec(firstElement(), 'return jQuery(arguments[0]).select2("val");')
    }

}

The original select did not work, but could be rewritten as shown.

Use the new NonEmptyNavigator when testing

Add this to GebConfig.groovy:

innerNavigatorFactory = { Browser browser, List<WebElement> elements ->

    elements ? new NonEmptyNavigator(browser, elements) : new EmptyNavigator(browser)

}

Differences between select and select2 in actual tests

The example shows part of code that is used for testing select user from list of users.

def usernameField = $('#usernameId')
// The userlist is on the format Fullname|Username
List<String> userList = userService.listNamesWithUsernameAsKey()
// select a random user
String selectedUsername = ListString.getKey(userList.get(random.nextInt(userList.size())))

// This is how to assign value to select
usernameField = selectedUsername
// While this is how to assign value to select2
usernameField.select(selectedUsername)

// This is how to get the selected value from a select
String currSelected = usernameField
// This is how to get same value from a select2
String currSelected2 = usernameField.getSelectedValue()