Create a screenshot of WebElements with WebDriver

Problem

Sometimes we like to create a screenshot of specific elements. It’s unnecessary to take a screenshot of the entire website. We can implement the following class to achieve this.

Solution


import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.Point;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.Augmenter;

public class TakeElementScreenshot {
    private final String screenshotFolder = "target/screenshots/";
    protected WebDriver driver;

    public TakeElementScreenshot(WebDriver driver) {
        this.driver = driver;
    }

    public void shoot(WebElement element) throws IOException {
        try {
            driver = new Augmenter().augment(driver);
        } catch (Exception ignored) {
        }
        File screen = ((TakesScreenshot) driver)
                .getScreenshotAs(OutputType.FILE);

        Point p = element.getLocation();

        int width = element.getSize().getWidth();
        int height = element.getSize().getHeight();

        Rectangle rect = new Rectangle(width, height);

        BufferedImage img = null;
        img = ImageIO.read(screen);

        BufferedImage dest = img.getSubimage(p.getX(), p.getY(), rect.width,
                rect.height);

        ImageIO.write(dest, "png", screen);
        FileUtils.copyFile(screen,
                new File(screenshotFolder + System.nanoTime() + ".png"));
    }

}

 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
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.Point;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.Augmenter;

public class TakeElementScreenshot {
    private final String screenshotFolder = "target/screenshots/";
    protected WebDriver driver;

    public TakeElementScreenshot(WebDriver driver) {
        this.driver = driver;
    }

    public void shoot(WebElement element) throws IOException {
        try {
            driver = new Augmenter().augment(driver);
        } catch (Exception ignored) {
        }
        File screen = ((TakesScreenshot) driver)
                .getScreenshotAs(OutputType.FILE);

        Point p = element.getLocation();

        int width = element.getSize().getWidth();
        int height = element.getSize().getHeight();

        Rectangle rect = new Rectangle(width, height);

        BufferedImage img = null;
        img = ImageIO.read(screen);

        BufferedImage dest = img.getSubimage(p.getX(), p.getY(), rect.width,
                rect.height);

        ImageIO.write(dest, "png", screen);
        FileUtils.copyFile(screen,
                new File(screenshotFolder + System.nanoTime() + ".png"));
    }

}

How to use it


@Test
public void takeScreenshotOfElement() throws IOException {
   // Find the text input element by its name
   WebElement element = driver.findElement(By.name("q"));

   // Enter something to search for
   element.sendKeys("Cheese!");
        
   // takescreenshot of element
   TakeElementScreenshot screenshot = new TakeElementScreenshot(driver);
   screenshot.shoot(element);

   // Now submit the form. WebDriver will find the form for us from the element
   element.submit();

   // Check the title of the page
   System.out.println("Page title is: " + driver.getTitle());
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
@Test
public void takeScreenshotOfElement() throws IOException {
   // Find the text input element by its name
   WebElement element = driver.findElement(By.name("q"));

   // Enter something to search for
   element.sendKeys("Cheese!");
        
   // takescreenshot of element
   TakeElementScreenshot screenshot = new TakeElementScreenshot(driver);
   screenshot.shoot(element);

   // Now submit the form. WebDriver will find the form for us from the element
   element.submit();

   // Check the title of the page
   System.out.println("Page title is: " + driver.getTitle());
}

What has been done…

We have made a screenshot of a specific element.

Code on Github

The code is available on Github at the following location: http://github.com/roydekleijn/WebDriver-take-screenshot-of-element

Voer je Selenium tests uit in de cloud met TestingBot

Idealiter wilt je de testscripts uit te voeren in alle verschillende browsers op alle platforms. Dit kan worden bereikt met Selenium Grid. Het opzetten van Selenium Grid kan een tijdrovende taak zijn en je hebt te maken met licentiekosten van de verschillende besturingssystemen. Daarom leveren sommige bedrijven cloud-gebaseerde oplossingen.

TestingBot biedt een cloud-gebaseerde oplossing met vele extra functionaliteiten, zoals: het nemen van screenshots, video-opname van de testuitvoering , geïntegreerde proxy en geavanceerde rapportage.

TestingBot kan worden gebruikt in allerlei programmeertalen. In deze tutorial zie je hoe makkelijk het is om tests uit te voeren in de cloud.

# Hoe te

  1. Maak een account op TestingBot en probeer het gratis. (of kies een maandelijks abonnement)
  2. Download de vereiste library: https://github.com/testingbot
  3. Wijzig het Remote adres, zodat de tests worden uitgevoerd op het externe Grid.

import java.net.URL;

import org.openqa.selenium.By;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class TestingBotTest {
    private WebDriver driver;

    @BeforeClass
    public void setUp() throws Exception {
        DesiredCapabilities capabillities = DesiredCapabilities.firefox();
        capabillities.setCapability("version", "11");
        capabillities.setCapability("platform", Platform.WINDOWS);
        capabillities.setCapability("name", "Testing Selenium 2");

        driver = new RemoteWebDriver(
                new URL(
                        "http://ClientKey:ClientSecret@hub.testingbot.com:4444/wd/hub"),
                capabillities);
    }

    @Test
    public void testSimple() throws Exception {
        driver.get("http://selenium.polteq.com/prestashop/");
        driver.findElement(By.cssSelector("input#search_query_top")).sendKeys(
                "ipod nano");
        driver.findElement(By.cssSelector("input[name='submit_search']"))
                .click();
        String searchHeader = driver.findElement(By.cssSelector("H1"))
                .getText().toLowerCase();

        Assert.assertTrue(searchHeader.contains("ipod nano"));
    }

    @AfterClass
    public void tearDown() throws Exception {
        driver.quit();
    }
}
 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
import java.net.URL;

import org.openqa.selenium.By;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class TestingBotTest {
    private WebDriver driver;

    @BeforeClass
    public void setUp() throws Exception {
        DesiredCapabilities capabillities = DesiredCapabilities.firefox();
        capabillities.setCapability("version", "11");
        capabillities.setCapability("platform", Platform.WINDOWS);
        capabillities.setCapability("name", "Testing Selenium 2");

        driver = new RemoteWebDriver(
                new URL(
                        "http://ClientKey:ClientSecret@hub.testingbot.com:4444/wd/hub"),
                capabillities);
    }

    @Test
    public void testSimple() throws Exception {
        driver.get("http://selenium.polteq.com/prestashop/");
        driver.findElement(By.cssSelector("input#search_query_top")).sendKeys(
                "ipod nano");
        driver.findElement(By.cssSelector("input[name='submit_search']"))
                .click();
        String searchHeader = driver.findElement(By.cssSelector("H1"))
                .getText().toLowerCase();

        Assert.assertTrue(searchHeader.contains("ipod nano"));
    }

    @AfterClass
    public void tearDown() throws Exception {
        driver.quit();
    }
}

Extra opties

Screenshots

Neem een screenshots bij elke stap van de test.


capabillities.setCapability("screenshot", true);
1
capabillities.setCapability("screenshot", true);

Video

Een video opnemen van uw test, die toegankelijk is in de member area.


capabillities.setCapability("screenrecorder", true);
1
capabillities.setCapability("screenrecorder", true);

Test Name

Voeg een naam toe aan de test, die zal verschijnen in onze member area.


capabillities.setCapability("name", "Test Script Name");
1
capabillities.setCapability("name", "Test Script Name");

Custom data

Stuur extra gegevens met de test mee, bijvoorbeeld uw build-nummer, release, server, enz. ..


capabillities.setCapability("extra", "release 1.2.3");
1
capabillities.setCapability("extra", "release 1.2.3");

Gebruik een eigen prioritizer voor de Selenium Grid Hub

Probleem

Stel je voor dat alle development/QA/CI computers de testscripts naar de HUB sturen. Ze komen dan in een wachtrij (queue) en zullen volgens het FIFO (First In – First Out) principe worden afgehandeld.

Ook de Continuous Integration (CI) testscripts kunnen naar dezelfde HUB worden gestuurd. Het is zeer gewenst om deze tests een hogere prioriteit te geven, omdat we de feedback-cycle zo kort mogelijk willen houden (we willen zo snel mogelijk weten of de build is geslaagd). Als we de hieronder beschreven code implementeren, dan kunnen we een onderscheid maken op basis van prioriteit.

Oplossing

  1. Maak de prioritizer
  2. Maak een JSON configuratie bestand (hub.json)
  3. Start de HUB met de eigen prioritizer
  4. Wijzig de testscripts

Maak de prioritizer


import java.util.Map;

import org.openqa.grid.internal.listeners.Prioritizer;

public class CustomPrioritizer implements Prioritizer {

    public int compareTo(Map<String, Object> a, Map<String, Object> b) {
        boolean aImportant = a.get("_important") == null ? false : Boolean
                .parseBoolean(a.get("_important").toString());
        boolean bImportant = b.get("_important") == null ? false : Boolean
                .parseBoolean(b.get("_important").toString());
        if (aImportant == bImportant) {
            return 0;
        }
        if (aImportant && !bImportant) {
            return -1;
        } else {
            return 1;
        }
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import java.util.Map;

import org.openqa.grid.internal.listeners.Prioritizer;

public class CustomPrioritizer implements Prioritizer {

    public int compareTo(Map<String, Object> a, Map<String, Object> b) {
        boolean aImportant = a.get("_important") == null ? false : Boolean
                .parseBoolean(a.get("_important").toString());
        boolean bImportant = b.get("_important") == null ? false : Boolean
                .parseBoolean(b.get("_important").toString());
        if (aImportant == bImportant) {
            return 0;
        }
        if (aImportant && !bImportant) {
            return -1;
        } else {
            return 1;
        }
    }
}

Maak een JSON configuratie bestand (hub.json)


{
  "host": null,
  "port": 4444,
  "newSessionWaitTimeout": -1,
  "servlets" : [],
  "prioritizer": myPriotizer.customPrioritizer,
  "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher",
  "throwOnCapabilityNotPresent": true,
  "nodePolling": 5000,

  "cleanUpCycle": 5000,
  "timeout": 300000,
  "maxSession": 20
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{
  "host": null,
  "port": 4444,
  "newSessionWaitTimeout": -1,
  "servlets" : [],
  "prioritizer": myPriotizer.customPrioritizer,
  "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher",
  "throwOnCapabilityNotPresent": true,
  "nodePolling": 5000,

  "cleanUpCycle": 5000,
  "timeout": 300000,
  "maxSession": 20
}

Start de HUB met de eigen prioritizer


java -cp selenium-server-standalone-<version>.jar:prioritizer.jar org.openqa.grid.selenium.GridLauncher -role hub -hubConfig hub.json
1
java -cp selenium-server-standalone-<version>.jar:prioritizer.jar org.openqa.grid.selenium.GridLauncher -role hub -hubConfig hub.json

Wijzig de testscripts


import java.net.MalformedURLException;
import java.net.URL;

import org.openqa.selenium.By;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.Assert;
import org.testng.annotations.Test;

public class PrioritizerExample {
    
    @Test
    public void importantTest() throws MalformedURLException {
        DesiredCapabilities capability = DesiredCapabilities.firefox();
        capability.setCapability("_important", true);
        
        RemoteWebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capability);
        driver.get("http://selenium.polteq.com/prestashop/");
        
        driver.findElement(By.cssSelector("input#search_query_top")).sendKeys("ipod nano");
        driver.findElement(By.cssSelector("input[name='submit_search']")).click();
        String searchHeader = driver.findElement(By.cssSelector("H1")).getText().toLowerCase();
        
        Assert.assertTrue(searchHeader.contains("ipod nano"));
        
        driver.close();
        driver.quit();
    }
    
    @Test
    public void lessImportantTest() throws MalformedURLException {
        DesiredCapabilities capability = DesiredCapabilities.firefox();
        capability.setCapability("_important", false);
        
        RemoteWebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capability);
        driver.get("http://selenium.polteq.com/prestashop/");
        
        driver.findElement(By.cssSelector("input#search_query_top")).sendKeys("ipod nano");
        driver.findElement(By.cssSelector("input[name='submit_search']")).click();
        String searchHeader = driver.findElement(By.cssSelector("H1")).getText().toLowerCase();
        
        Assert.assertTrue(searchHeader.contains("ipod nano"));
        
        driver.close();
        driver.quit();
    }

}
 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
import java.net.MalformedURLException;
import java.net.URL;

import org.openqa.selenium.By;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.Assert;
import org.testng.annotations.Test;

public class PrioritizerExample {
    
    @Test
    public void importantTest() throws MalformedURLException {
        DesiredCapabilities capability = DesiredCapabilities.firefox();
        capability.setCapability("_important", true);
        
        RemoteWebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capability);
        driver.get("http://selenium.polteq.com/prestashop/");
        
        driver.findElement(By.cssSelector("input#search_query_top")).sendKeys("ipod nano");
        driver.findElement(By.cssSelector("input[name='submit_search']")).click();
        String searchHeader = driver.findElement(By.cssSelector("H1")).getText().toLowerCase();
        
        Assert.assertTrue(searchHeader.contains("ipod nano"));
        
        driver.close();
        driver.quit();
    }
    
    @Test
    public void lessImportantTest() throws MalformedURLException {
        DesiredCapabilities capability = DesiredCapabilities.firefox();
        capability.setCapability("_important", false);
        
        RemoteWebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capability);
        driver.get("http://selenium.polteq.com/prestashop/");
        
        driver.findElement(By.cssSelector("input#search_query_top")).sendKeys("ipod nano");
        driver.findElement(By.cssSelector("input[name='submit_search']")).click();
        String searchHeader = driver.findElement(By.cssSelector("H1")).getText().toLowerCase();
        
        Assert.assertTrue(searchHeader.contains("ipod nano"));
        
        driver.close();
        driver.quit();
    }

}

Selenium node opstarten met een JSON configuratie bestand

Probleem

We kunnen parameters aan de Selenium node meegeven om deze zo te configureren. We kunnen bijvoorbeeld het maximum aan gelijktijdige tests, platform, browser naam en nog andere parameters instellen. We gebruiken deze waarden om vanuit onze test de juiste node te selecteren.

Voorwaarden

Open de command prompt en navigeer naar de map waar selenium-server-standalone.jar is opgeslagen.

Oplossing

We kunnen een -browser parameter aan de command-line toevoegen met de volgende waarden om 5 FireFox 3.6 instanties op Linux te starten.

-browser browserName=firefox,version=3.6,maxInstances=5,platform=LINUX

Er is meer…

We kunnen ook een JSON bestand tijdens het starten van de node meeladen, in plaats van de -browser command-line parameter te specificeren. We moeten dan de volgende parameter aan de command-line meegeven: -nodeConfig node.json. De inhoud van het JSON bestand kan er als volgt uit zien:


{
  "capabilities":
      [
        {
          "browserName": "firefox",
          "version": "3.6",
          "platform": "WINDOWS",
          "maxInstances": 1
        },
        {
          "browserName": "internet explorer",
          "version": "8",
          "platform": "WINDOWS",
          "maxInstances": 1
        }
      ],
    "configuration":
        {
        "nodeTimeout":120,
        "port":5555,

        "hubPort":4444,
        "hubHost":"localhost",

        "nodePolling":2000,

        "registerCycle":10000,
        "register":true,
        "cleanUpCycle":2000,
        "timeout":30000,
        "maxSession":1,
        }
}
 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
{
  "capabilities":
      [
        {
          "browserName": "firefox",
          "version": "3.6",
          "platform": "WINDOWS",
          "maxInstances": 1
        },
        {
          "browserName": "internet explorer",
          "version": "8",
          "platform": "WINDOWS",
          "maxInstances": 1
        }
      ],
    "configuration":
        {
        "nodeTimeout":120,
        "port":5555,

        "hubPort":4444,
        "hubHost":"localhost",

        "nodePolling":2000,

        "registerCycle":10000,
        "register":true,
        "cleanUpCycle":2000,
        "timeout":30000,
        "maxSession":1,
        }
}

Bovenstaande JSON configuratie maakt het mogelijk om een FireFox en Internet Explorer browser op een Windows platform te starten.

Command-line commando voor het starten van een Selenium Node met een JSON configuratie bestand:

java -jar selenium-server-standalone-<version>.jar -role node -hub http://localhost:4444/grid/register -nodeConfig defaultNodeConfig.json

Running tests against the Grid

Problem

We have to make minor changes to the tests in order to run our tests against the Grid. This recipes will show us how we can define capabilities to match a node.

Prerequisites

Make sure the desired capabilities are in the Grid otherwise the test can not be routed to the node.

Solution

The code below will match the following nodes: browserName=firefox,version=3.6,platform=LINUX


import java.net.MalformedURLException;
import java.net.URL;

import org.openqa.selenium.By;
import org.openqa.selenium.Platform;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class GridExample {
    private static RemoteWebDriver driver;
    
    @BeforeClass
    public void setUp() throws MalformedURLException {
        DesiredCapabilities capability = DesiredCapabilities.firefox();
        capability.setBrowserName("firefox");
        capability.setPlatform(Platform.LINUX);
        capability.setVersion("3.6");
        driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capability);
        driver.get("http://selenium.polteq.com/prestashop/");
    }
    
    @Test
    public void measurePerformance() {
        driver.findElement(By.cssSelector("input#search_query_top")).sendKeys("ipod nano");
        driver.findElement(By.cssSelector("input[name='submit_search']")).click();
        String searchHeader = driver.findElement(By.cssSelector("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 java.net.MalformedURLException;
import java.net.URL;

import org.openqa.selenium.By;
import org.openqa.selenium.Platform;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class GridExample {
    private static RemoteWebDriver driver;
    
    @BeforeClass
    public void setUp() throws MalformedURLException {
        DesiredCapabilities capability = DesiredCapabilities.firefox();
        capability.setBrowserName("firefox");
        capability.setPlatform(Platform.LINUX);
        capability.setVersion("3.6");
        driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capability);
        driver.get("http://selenium.polteq.com/prestashop/");
    }
    
    @Test
    public void measurePerformance() {
        driver.findElement(By.cssSelector("input#search_query_top")).sendKeys("ipod nano");
        driver.findElement(By.cssSelector("input[name='submit_search']")).click();
        String searchHeader = driver.findElement(By.cssSelector("H1")).getText().toLowerCase();
        
        Assert.assertTrue(searchHeader.contains("ipod nano"));
    }
}

Adding nodes to the hub

Problem

We can add nodes to the Selenium Grid Hub, now the hub is up and running. This recipe will describe how to launch Selenium instances and register them to the hub so it starts forming the grid op Selenium instances that we are expecting.

Prerequisites

Open the command prompt and navigate to the directory where we put the selenium-server-standalone file.

Solution

Enter something like the following command in the command prompt: java -jar selenium-server-standalone-.jar -role node -hub http://localhost:4444/grid/register -port 5556 We should see the following output in the console:

What has been done

The command above will register a node to the hub, which is fully backwards compatible with Selenium 1. We can see this node in the Hub Console:

We can add multiple operating systems to our Selenium Grid. This allows us to check, whether different versions of Firefox on different operating systems are showing the same behavior.

Opstarten van de HUB

Probleem

De HUB is het centrale punt in het Grid, dat alle Selenium commando’s ontvangt en distribueert naar de juiste nodes. In deze tutorial zien we hoe de HUB gestart kan worden.

Voorwaarden

Download the latest version of selenium-server-standalone.jar from the Selenium website. (http://code.google.com/p/selenium/downloads/list) Open the command prompt and navigate to the directory where we put the selenium-server-standalone file.

Oplossing

Voer het volgende commando in de command prompt om de HUB te starten: java -jar selenium-server-standalone-.jar -role hub De output in de console ziet er als volgt uit:

Wat is er gedaan

De Hub gebruikt standaard poort 4444. We kunnen de Selenium-instanties die zijn aangesloten op de hub en de status ervan als we naar http://ip-of-hub:4444/grid/console gaan, waarbij ip-of-hub het ip-adres van de machine waarop de Hub draait is. Als het de locale machine is dan kunnen we naar http://localhost:4444/grid/console gaan. Dat kunnen we zien in het volgende screenshot:

Tip: We kunnen de Hub ook starten op een andere poort. We kunnen een extra parameter aan het commando meegeven, zoals: -port # (waarbij # het poort nummer is)

Selenium Grid 2 – Introductie

Met Selenium Grid is het mogelijk om meerdere Selenium instanties op een of meerdere computers te draaien. Al deze instanties zijn met elkaar verbonden, vanuit de testscripts hoeven we alleen maar de centrale HUB aan te spreken. De centrale HUB distribueert de testscripts dan over het Grid van Selenium instanties.

In dit deel van het blog zien we hoe er van Selenium Grid gebruik kan worden gemaakt.

Running tests on an Android simulator

Probleem

The android driver allows us to execute our tests against an Android browser. This can be a simulator or a real device. This recipe will walk us through the steps we have to do to run our tests in a simulator.

Voorwaarden

Before we can register our simulator we have to download the android SDK (Software Development Kit) from the following location: http://developer.android.com/sdk/

Oplossing

We can divide this section into three parts: setup the emulator, install the WebDriver APK and finally run the test.

Setup the emulator

Navigate to the tools directory and create an Android Virtual Device.


$cd ~/android_sdk/tools/
$./android create avd -n my_android -t 12 -c 100M
1
2
$cd ~/android_sdk/tools/
$./android create avd -n my_android -t 12 -c 100M

-n: specifies the name of the AVD -t: specifies the platform target -c: specifies the SD card storage space

We can list the targets with the following command to check if the creation succeeded:

./android list targets

Finally we can start the emulator with the following command:

$./emulator -avd my_android &

Install the WebDriver APK

  1. We need to retrieve the serial id with the following command: $~/android_sdk/platform-tools/adb devices
  2. Download the Android server from http://code.google.com/p/selenium/downloads/list and save it in the platform-tools directory. To install the application enter: $./adb -s -e install -r android-server.apk
  3. Start the Android WebDriver application,by running this command: $./adb -s shell am start -a android.intent.action.MAIN -n org.openqa.selenium.android.app/.MainActivity
  4. Now we need to setup the port forwarding in order to forward traffic from the host machine to the emulator. Enter the following in the terminal: $./adb -s forward tcp:8080 tcp:8080

Run the test

Now we have our environment setup we can run our tests. The test will look like this:


import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.android.AndroidDriver;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class MobileAndroidDevice {
    private static WebDriver driver;
    
    @BeforeClass
    public void setUp() throws Exception {
        driver = new AndroidDriver();
        driver.get("http://selenium.polteq.com/prestashop/");
    }
    
    @AfterClass
    public void tearDown() {
        driver.close();
        driver.quit();
    }
    
    @Test
    public void measurePerformance() throws InterruptedException {
        Thread.sleep(1500);
        driver.findElement(By.cssSelector("input#search_query_top")).sendKeys("ipod nano");
        driver.findElement(By.cssSelector("input[name='submit_search']")).click();
        String searchHeader = driver.findElement(By.cssSelector("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.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.android.AndroidDriver;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class MobileAndroidDevice {
    private static WebDriver driver;
    
    @BeforeClass
    public void setUp() throws Exception {
        driver = new AndroidDriver();
        driver.get("http://selenium.polteq.com/prestashop/");
    }
    
    @AfterClass
    public void tearDown() {
        driver.close();
        driver.quit();
    }
    
    @Test
    public void measurePerformance() throws InterruptedException {
        Thread.sleep(1500);
        driver.findElement(By.cssSelector("input#search_query_top")).sendKeys("ipod nano");
        driver.findElement(By.cssSelector("input[name='submit_search']")).click();
        String searchHeader = driver.findElement(By.cssSelector("H1")).getText().toLowerCase();
            
        Assert.assertTrue(searchHeader.contains("ipod nano"));
    }
}