Injecting the Sizzle CSS selector library

Probleem

We kunnen wat problemen ervaren met het lokaliseren van elementbij de implementatie van WebDriver. Deze problemen komen naar voren, omdat WebDriver strikt de CSS standaard volgt. Bijvoorbeeld :contains(‘text’) werkt niet meer. De oplossing is het injecteren van de Sizzle engine in de browser waar de tests in worden uitgevoerd. Door het maken van een aparte SizzleSelector class kunnen we *SizzleSelector *eenvoudig gebruiken.

Oplossing

Dit is de code van de SizzleSelector class. Het injecteerd, met gebruik van Javascript, de Sizzle engine in de browser.


import java.util.List;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;
 
@SuppressWarnings("unchecked")
public class SizzleSelector {
    private JavascriptExecutor driver;
 
    public SizzleSelector(WebDriver webDriver) {
        driver = (JavascriptExecutor) webDriver;
    }
 
    public WebElement findElementBySizzleCss(String using) {
        injectSizzleIfNeeded();
        String javascriptExpression = createSizzleSelectorExpression(using);
        List<WebElement> elements = (List<WebElement>) driver
                .executeScript(javascriptExpression);
        if (elements.size() > 0)
            return (WebElement) elements.get(0);
        return null;
    }
 
    public List<WebElement> findElementsBySizzleCss(String using) {
        injectSizzleIfNeeded();
        String javascriptExpression = createSizzleSelectorExpression(using);
        return (List<WebElement>) driver.executeScript(javascriptExpression);
    }
 
    private String createSizzleSelectorExpression(String using) {
        return "return Sizzle(\"" + using + "\")";
    }
 
    private void injectSizzleIfNeeded() {
        if (!sizzleLoaded())
            injectSizzle();
    }
 
    public Boolean sizzleLoaded() {
        Boolean loaded;
        try {
            loaded = (Boolean) driver.executeScript("return Sizzle()!=null");
        } catch (WebDriverException e) {
            loaded = false;
        }
        return loaded;
    }
 
    public void injectSizzle() {
        driver.executeScript(" var headID = document.getElementsByTagName(\"head\")[0];"
                + "var newScript = document.createElement('script');"
                + "newScript.type = 'text/javascript';"
                + "newScript.src = 'https://raw.github.com/jquery/sizzle/master/sizzle.js';"
                + "headID.appendChild(newScript);");
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import java.util.List;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;
 
@SuppressWarnings("unchecked")
public class SizzleSelector {
    private JavascriptExecutor driver;
 
    public SizzleSelector(WebDriver webDriver) {
        driver = (JavascriptExecutor) webDriver;
    }
 
    public WebElement findElementBySizzleCss(String using) {
        injectSizzleIfNeeded();
        String javascriptExpression = createSizzleSelectorExpression(using);
        List<WebElement> elements = (List<WebElement>) driver
                .executeScript(javascriptExpression);
        if (elements.size() > 0)
            return (WebElement) elements.get(0);
        return null;
    }
 
    public List<WebElement> findElementsBySizzleCss(String using) {
        injectSizzleIfNeeded();
        String javascriptExpression = createSizzleSelectorExpression(using);
        return (List<WebElement>) driver.executeScript(javascriptExpression);
    }
 
    private String createSizzleSelectorExpression(String using) {
        return "return Sizzle(\"" + using + "\")";
    }
 
    private void injectSizzleIfNeeded() {
        if (!sizzleLoaded())
            injectSizzle();
    }
 
    public Boolean sizzleLoaded() {
        Boolean loaded;
        try {
            loaded = (Boolean) driver.executeScript("return Sizzle()!=null");
        } catch (WebDriverException e) {
            loaded = false;
        }
        return loaded;
    }
 
    public void injectSizzle() {
        driver.executeScript(" var headID = document.getElementsByTagName(\"head\")[0];"
                + "var newScript = document.createElement('script');"
                + "newScript.type = 'text/javascript';"
                + "newScript.src = 'https://raw.github.com/jquery/sizzle/master/sizzle.js';"
                + "headID.appendChild(newScript);");
    }
}

Hoe te gebruiken

De class die hierboven is beschreven injecteert de Sizzle engine in de browser. Dit steld ons in staat om alle Sizzle selector features te gebruiken, zoals :contains(‘text’). Andere classes extenden deze class en dan is het mogelijk om findElementBySizzleCss() te gebruiken bij het lokaliseren van elementen.


import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class SizzleExample {
    private static WebDriver driver;
    SizzleSelector sizzle;
    
    @BeforeClass
    public void setUp() {
        driver = new FirefoxDriver();
        sizzle = new SizzleSelector(driver);
        driver.get("http://selenium.polteq.com/prestashop/");
    }
    
    @AfterClass
    public void tearDown() {
        driver.close();
        driver.quit();
    }
    
    @Test
    public void useSizzleSelector() {
        sizzle.findElementBySizzleCss("input#search_query_top").sendKeys("ipod nano");
        sizzle.findElementBySizzleCss("input[name='submit_search']").click();
        String searchHeader =  sizzle.findElementBySizzleCss("H1").getText().toLowerCase();
        
        Assert.assertTrue(searchHeader.contains("ipod nano"));
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class SizzleExample {
    private static WebDriver driver;
    SizzleSelector sizzle;
    
    @BeforeClass
    public void setUp() {
        driver = new FirefoxDriver();
        sizzle = new SizzleSelector(driver);
        driver.get("http://selenium.polteq.com/prestashop/");
    }
    
    @AfterClass
    public void tearDown() {
        driver.close();
        driver.quit();
    }
    
    @Test
    public void useSizzleSelector() {
        sizzle.findElementBySizzleCss("input#search_query_top").sendKeys("ipod nano");
        sizzle.findElementBySizzleCss("input[name='submit_search']").click();
        String searchHeader =  sizzle.findElementBySizzleCss("H1").getText().toLowerCase();
        
        Assert.assertTrue(searchHeader.contains("ipod nano"));
    }
}

Injecting the Sizzle CSS selector library
7 votes, 4.57 avg. rating (90% score)