From dfbb5e3a5c38f93a77ac64924bb0e0fb11702cd2 Mon Sep 17 00:00:00 2001 From: michada Date: Sun, 16 Feb 2014 00:17:16 +0100 Subject: [PATCH] Tests for people management functionality added. DAO class modified to support and alternative JNDI for the data source through the "db.jndi" system property. A new testing database resource was added to the Context.xml file. DAO tests use the "spring-test" library to create a JNDI context, as JUnit doesn't create any context. Additionaly, a custom DataSource is created using the "commons-dbcp" library and injected into the context. Testing database creation scripts are provided in the mysql-tests.sql file. REST API is tested in the server side using the "jersey-test-framework-provider-grizzly2" library. These tests also use the "spring-test" and "commons-dbcp" libraries to create a context and inject a custom data source. REST API is tested in the client side using the "Selenium IDE" and "RESTClient" plugins for Firefox. Manual database reset is required before launching the test suite. Web interface is tested using the "Selenium IDE" plugin for Firefox and using the "Selenium WebDrive" in JUnit tests. Same tests are implemented in both cases. Selenium IDE tests require a manual database reset before launching the test suite. JUnit test require the server to be started using the testing database. --- pom.xml | 28 +++ src/main/java/es/uvigo/esei/daa/dao/DAO.java | 5 +- src/main/webapp/META-INF/context.xml | 20 +- .../es/uvigo/esei/daa/PeopleTestSuite.java | 14 ++ .../java/es/uvigo/esei/daa/TestUtils.java | 84 ++++++++ .../es/uvigo/esei/daa/dao/PeopleDAOTest.java | 113 ++++++++++ .../es/uvigo/esei/daa/mysql-tests-clear.sql | 4 + .../java/es/uvigo/esei/daa/mysql-tests.sql | 28 +++ .../es/uvigo/esei/daa/rest/PeopleTest.java | 195 ++++++++++++++++++ .../es/uvigo/esei/daa/web/PeopleWebTest.java | 137 ++++++++++++ src/test/webapp/rest/people/add.html | 132 ++++++++++++ src/test/webapp/rest/people/addNoName.html | 107 ++++++++++ src/test/webapp/rest/people/addNoSurname.html | 107 ++++++++++ src/test/webapp/rest/people/delete.html | 77 +++++++ .../webapp/rest/people/deleteInvalidId.html | 77 +++++++ src/test/webapp/rest/people/get.html | 96 +++++++++ src/test/webapp/rest/people/list.html | 96 +++++++++ src/test/webapp/rest/people/modify.html | 132 ++++++++++++ .../webapp/rest/people/modifyInvalidId.html | 107 ++++++++++ src/test/webapp/rest/people/modifyNoId.html | 107 ++++++++++ src/test/webapp/rest/people/modifyNoName.html | 107 ++++++++++ .../webapp/rest/people/modifyNoSurname.html | 107 ++++++++++ src/test/webapp/rest/people/rest.html | 24 +++ src/test/webapp/web/people/add.html | 71 +++++++ src/test/webapp/web/people/delete.html | 76 +++++++ src/test/webapp/web/people/edit.html | 82 ++++++++ src/test/webapp/web/people/example.html | 17 ++ src/test/webapp/web/people/list.html | 46 +++++ 28 files changed, 2192 insertions(+), 4 deletions(-) create mode 100644 src/test/java/es/uvigo/esei/daa/PeopleTestSuite.java create mode 100644 src/test/java/es/uvigo/esei/daa/TestUtils.java create mode 100644 src/test/java/es/uvigo/esei/daa/dao/PeopleDAOTest.java create mode 100644 src/test/java/es/uvigo/esei/daa/mysql-tests-clear.sql create mode 100644 src/test/java/es/uvigo/esei/daa/mysql-tests.sql create mode 100644 src/test/java/es/uvigo/esei/daa/rest/PeopleTest.java create mode 100644 src/test/java/es/uvigo/esei/daa/web/PeopleWebTest.java create mode 100644 src/test/webapp/rest/people/add.html create mode 100644 src/test/webapp/rest/people/addNoName.html create mode 100644 src/test/webapp/rest/people/addNoSurname.html create mode 100644 src/test/webapp/rest/people/delete.html create mode 100644 src/test/webapp/rest/people/deleteInvalidId.html create mode 100644 src/test/webapp/rest/people/get.html create mode 100644 src/test/webapp/rest/people/list.html create mode 100644 src/test/webapp/rest/people/modify.html create mode 100644 src/test/webapp/rest/people/modifyInvalidId.html create mode 100644 src/test/webapp/rest/people/modifyNoId.html create mode 100644 src/test/webapp/rest/people/modifyNoName.html create mode 100644 src/test/webapp/rest/people/modifyNoSurname.html create mode 100644 src/test/webapp/rest/people/rest.html create mode 100644 src/test/webapp/web/people/add.html create mode 100644 src/test/webapp/web/people/delete.html create mode 100644 src/test/webapp/web/people/edit.html create mode 100644 src/test/webapp/web/people/example.html create mode 100644 src/test/webapp/web/people/list.html diff --git a/pom.xml b/pom.xml index 6745044..7f81e9d 100644 --- a/pom.xml +++ b/pom.xml @@ -28,6 +28,34 @@ test + + commons-dbcp + commons-dbcp + 1.4 + test + + + + org.seleniumhq.selenium + selenium-java + 2.39.0 + test + + + + org.springframework + spring-test + 4.0.0.RELEASE + test + + + + org.glassfish.jersey.test-framework.providers + jersey-test-framework-provider-grizzly2 + 2.5.1 + test + + org.glassfish.jersey.containers jersey-container-servlet diff --git a/src/main/java/es/uvigo/esei/daa/dao/DAO.java b/src/main/java/es/uvigo/esei/daa/dao/DAO.java index 0b82b80..e3822ee 100644 --- a/src/main/java/es/uvigo/esei/daa/dao/DAO.java +++ b/src/main/java/es/uvigo/esei/daa/dao/DAO.java @@ -17,8 +17,11 @@ public abstract class DAO { Context initContext; try { initContext = new InitialContext(); - this.dataSource = (DataSource) initContext.lookup(JNDI_NAME); + this.dataSource = (DataSource) initContext.lookup( + System.getProperty("db.jndi", JNDI_NAME) + ); } catch (NamingException e) { + e.printStackTrace(); throw new RuntimeException(e); } } diff --git a/src/main/webapp/META-INF/context.xml b/src/main/webapp/META-INF/context.xml index 17a6b1d..d8b997c 100644 --- a/src/main/webapp/META-INF/context.xml +++ b/src/main/webapp/META-INF/context.xml @@ -19,7 +19,21 @@ - + + + \ No newline at end of file diff --git a/src/test/java/es/uvigo/esei/daa/PeopleTestSuite.java b/src/test/java/es/uvigo/esei/daa/PeopleTestSuite.java new file mode 100644 index 0000000..329217c --- /dev/null +++ b/src/test/java/es/uvigo/esei/daa/PeopleTestSuite.java @@ -0,0 +1,14 @@ +package es.uvigo.esei.daa; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +import es.uvigo.esei.daa.dao.PeopleDAOTest; +import es.uvigo.esei.daa.rest.PeopleTest; +import es.uvigo.esei.daa.web.PeopleWebTest; + +@SuiteClasses({ PeopleDAOTest.class, PeopleTest.class, PeopleWebTest.class }) +@RunWith(Suite.class) +public class PeopleTestSuite { +} diff --git a/src/test/java/es/uvigo/esei/daa/TestUtils.java b/src/test/java/es/uvigo/esei/daa/TestUtils.java new file mode 100644 index 0000000..b186037 --- /dev/null +++ b/src/test/java/es/uvigo/esei/daa/TestUtils.java @@ -0,0 +1,84 @@ +package es.uvigo.esei.daa; + +import static org.junit.Assert.assertEquals; + +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; + +import javax.naming.NamingException; +import javax.sql.DataSource; +import javax.ws.rs.core.Response; + +import org.apache.commons.dbcp.BasicDataSource; +import org.springframework.mock.jndi.SimpleNamingContextBuilder; + + +public final class TestUtils { + private TestUtils() {} + + public static void createFakeContext() throws NamingException { + final SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder(); + builder.bind("java:/comp/env/jdbc/daaexample", createTestingDataSource()); + builder.activate(); + } + + private static BasicDataSource createTestingDataSource() { + final BasicDataSource ds = new BasicDataSource(); + ds.setDriverClassName("com.mysql.jdbc.Driver"); + ds.setUrl("jdbc:mysql://localhost:3306/daaexampletest?allowMultiQueries=true"); + ds.setUsername("daa"); + ds.setPassword("daa"); + ds.setMaxActive(100); + ds.setMaxIdle(30); + ds.setMaxWait(10000); + return ds; + } + + public static void clearTestDatabase() throws SQLException { + final String queries = new StringBuilder() + .append("DELETE FROM `people`;") + .append("DELETE FROM `users`;") + .toString(); + + final DataSource ds = createTestingDataSource(); + try (Connection connection = ds.getConnection()) { + try (Statement statement = connection.createStatement()) { + statement.execute(queries); + } + } + } + + public static void initTestDatabase() throws SQLException { + final String queries = new StringBuilder() + .append("ALTER TABLE `people` AUTO_INCREMENT = 1;") + .append("ALTER TABLE `users` AUTO_INCREMENT = 1;") + .append("INSERT INTO `people` (`id`,`name`,`surname`) VALUES (0, 'Antón', 'Álvarez');") + .append("INSERT INTO `people` (`id`,`name`,`surname`) VALUES (0, 'Ana', 'Amargo');") + .append("INSERT INTO `people` (`id`,`name`,`surname`) VALUES (0, 'Manuel', 'Martínez');") + .append("INSERT INTO `people` (`id`,`name`,`surname`) VALUES (0, 'María', 'Márquez');") + .append("INSERT INTO `people` (`id`,`name`,`surname`) VALUES (0, 'Lorenzo', 'López');") + .append("INSERT INTO `people` (`id`,`name`,`surname`) VALUES (0, 'Laura', 'Laredo');") + .append("INSERT INTO `people` (`id`,`name`,`surname`) VALUES (0, 'Perico', 'Palotes');") + .append("INSERT INTO `people` (`id`,`name`,`surname`) VALUES (0, 'Patricia', 'Pérez');") + .append("INSERT INTO `people` (`id`,`name`,`surname`) VALUES (0, 'Juan', 'Jiménez');") + .append("INSERT INTO `people` (`id`,`name`,`surname`) VALUES (0, 'Julia', 'Justa');") + .append("INSERT INTO `users` (`login`,`password`) VALUES ('mrjato', '59189332a4abf8ddf66fde068cad09eb563b4bd974f7663d97ff6852a7910a73');") + .toString(); + + final DataSource ds = createTestingDataSource(); + try (Connection connection = ds.getConnection()) { + try (Statement statement = connection.createStatement()) { + statement.execute(queries); + } + } + } + + public static void assertOkStatus(final Response response) { + assertEquals("Unexpected status code", Response.Status.OK.getStatusCode(), response.getStatus()); + } + + public static void assertBadRequestStatus(final Response response) { + assertEquals("Unexpected status code", Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus()); + } +} diff --git a/src/test/java/es/uvigo/esei/daa/dao/PeopleDAOTest.java b/src/test/java/es/uvigo/esei/daa/dao/PeopleDAOTest.java new file mode 100644 index 0000000..0e527b3 --- /dev/null +++ b/src/test/java/es/uvigo/esei/daa/dao/PeopleDAOTest.java @@ -0,0 +1,113 @@ +package es.uvigo.esei.daa.dao; + +import static org.junit.Assert.assertEquals; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import es.uvigo.esei.daa.TestUtils; +import es.uvigo.esei.daa.entities.Person; + +public class PeopleDAOTest { + private PeopleDAO dao; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + TestUtils.createFakeContext(); + } + + @Before + public void setUp() throws Exception { + TestUtils.initTestDatabase(); + this.dao = new PeopleDAO(); + } + + @After + public void tearDown() throws Exception { + TestUtils.clearTestDatabase(); + this.dao = null; + } + + @Test + public void testGet() throws DAOException { + final Person person = this.dao.get(4); + + assertEquals(4, person.getId()); + assertEquals("María", person.getName()); + assertEquals("Márquez", person.getSurname()); + } + + @Test(expected = IllegalArgumentException.class) + public void testGetInvalidId() throws DAOException { + this.dao.get(100); + } + + @Test + public void testList() throws DAOException { + assertEquals(10, this.dao.list().size()); + } + + @Test + public void testDelete() throws DAOException { + this.dao.delete(4); + + assertEquals(9, this.dao.list().size()); + } + + @Test(expected = IllegalArgumentException.class) + public void testDeleteInvalidId() throws DAOException { + this.dao.delete(100); + } + + @Test + public void testModify() throws DAOException { + this.dao.modify(5, "John", "Doe"); + + final Person person = this.dao.get(5); + + assertEquals(5, person.getId()); + assertEquals("John", person.getName()); + assertEquals("Doe", person.getSurname()); + } + + @Test(expected = IllegalArgumentException.class) + public void testModifyInvalidId() throws DAOException { + this.dao.modify(100, "John", "Doe"); + } + + @Test(expected = IllegalArgumentException.class) + public void testModifyNullName() throws DAOException { + this.dao.modify(5, null, "Doe"); + } + + @Test(expected = IllegalArgumentException.class) + public void testModifyNullSurname() throws DAOException { + this.dao.modify(5, "John", null); + } + + @Test + public void testAdd() throws DAOException { + final Person person = this.dao.add("John", "Doe"); + + assertEquals("John", person.getName()); + assertEquals("Doe", person.getSurname()); + + final Person personGet = this.dao.get(person.getId()); + + assertEquals(person.getId(), personGet.getId()); + assertEquals("John", personGet.getName()); + assertEquals("Doe", personGet.getSurname()); + } + + @Test(expected = IllegalArgumentException.class) + public void testAddNullName() throws DAOException { + this.dao.add(null, "Doe"); + } + + @Test(expected = IllegalArgumentException.class) + public void testAddNullSurname() throws DAOException { + this.dao.add("John", null); + } +} diff --git a/src/test/java/es/uvigo/esei/daa/mysql-tests-clear.sql b/src/test/java/es/uvigo/esei/daa/mysql-tests-clear.sql new file mode 100644 index 0000000..834c7cd --- /dev/null +++ b/src/test/java/es/uvigo/esei/daa/mysql-tests-clear.sql @@ -0,0 +1,4 @@ +DELETE FROM `people`; +DELETE FROM `users`; +ALTER TABLE `people` AUTO_INCREMENT = 1; +ALTER TABLE `users` AUTO_INCREMENT = 1; \ No newline at end of file diff --git a/src/test/java/es/uvigo/esei/daa/mysql-tests.sql b/src/test/java/es/uvigo/esei/daa/mysql-tests.sql new file mode 100644 index 0000000..72a0f26 --- /dev/null +++ b/src/test/java/es/uvigo/esei/daa/mysql-tests.sql @@ -0,0 +1,28 @@ +DROP TABLE IF EXISTS `people`; +CREATE TABLE `people` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(50) DEFAULT NULL, + `surname` varchar(100) DEFAULT NULL, + PRIMARY KEY (`id`) +); + +DROP TABLE IF EXISTS `users`; +CREATE TABLE `users` ( + `login` varchar(100) NOT NULL, + `password` varbinary(64) DEFAULT NULL, + PRIMARY KEY (`login`) +); + +INSERT INTO `people` (`id`,`name`,`surname`) VALUES (0,'Antón','Álvarez'); +INSERT INTO `people` (`id`,`name`,`surname`) VALUES (0,'Ana','Amargo'); +INSERT INTO `people` (`id`,`name`,`surname`) VALUES (0,'Manuel','Martínez'); +INSERT INTO `people` (`id`,`name`,`surname`) VALUES (0,'María','Márquez'); +INSERT INTO `people` (`id`,`name`,`surname`) VALUES (0,'Lorenzo','López'); +INSERT INTO `people` (`id`,`name`,`surname`) VALUES (0,'Laura','Laredo'); +INSERT INTO `people` (`id`,`name`,`surname`) VALUES (0,'Perico','Palotes'); +INSERT INTO `people` (`id`,`name`,`surname`) VALUES (0,'Patricia','Pérez'); +INSERT INTO `people` (`id`,`name`,`surname`) VALUES (0,'Juan','Jiménez'); +INSERT INTO `people` (`id`,`name`,`surname`) VALUES (0,'Julia','Justa'); + +-- login: mrjato, password: mrjato +INSERT INTO `users` (`login`,`password`) VALUES ('mrjato', '59189332a4abf8ddf66fde068cad09eb563b4bd974f7663d97ff6852a7910a73'); diff --git a/src/test/java/es/uvigo/esei/daa/rest/PeopleTest.java b/src/test/java/es/uvigo/esei/daa/rest/PeopleTest.java new file mode 100644 index 0000000..e3fc466 --- /dev/null +++ b/src/test/java/es/uvigo/esei/daa/rest/PeopleTest.java @@ -0,0 +1,195 @@ +package es.uvigo.esei.daa.rest; + +import static es.uvigo.esei.daa.TestUtils.assertOkStatus; +import static es.uvigo.esei.daa.TestUtils.assertBadRequestStatus; +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.util.List; + +import javax.ws.rs.client.Entity; +import javax.ws.rs.core.Application; +import javax.ws.rs.core.Form; +import javax.ws.rs.core.GenericType; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.codehaus.jackson.jaxrs.JacksonJsonProvider; +import org.glassfish.jersey.client.ClientConfig; +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.test.JerseyTest; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import es.uvigo.esei.daa.TestUtils; +import es.uvigo.esei.daa.entities.Person; + +public class PeopleTest extends JerseyTest { + @BeforeClass + public static void setUpBeforeClass() throws Exception { + TestUtils.createFakeContext(); + } + + @Before + public void setUp() throws Exception { + super.setUp(); + TestUtils.initTestDatabase(); + } + + @After + public void tearDown() throws Exception { + super.tearDown(); + + TestUtils.clearTestDatabase(); + } + + @Override + protected Application configure() { + return new ResourceConfig(People.class) + .register(JacksonJsonProvider.class) + .property("com.sun.jersey.api.json.POJOMappingFeature", Boolean.TRUE); + } + + @Override + protected void configureClient(ClientConfig config) { + super.configureClient(config); + + config.register(JacksonJsonProvider.class); + config.property("com.sun.jersey.api.json.POJOMappingFeature", Boolean.TRUE); + } + + @Test + public void testList() throws IOException { + final Response response = target("people").request().get(); + assertOkStatus(response); + + final List people = response.readEntity(new GenericType>(){}); + assertEquals(10, people.size()); + } + + @Test + public void testGet() throws IOException { + final Response response = target("people/4").request().get(); + assertOkStatus(response); + + final Person person = response.readEntity(Person.class); + assertEquals(4, person.getId()); + assertEquals("María", person.getName()); + assertEquals("Márquez", person.getSurname()); + } + + @Test + public void testGetInvalidId() throws IOException { + assertBadRequestStatus(target("people/100").request().get()); + } + + @Test + public void testAdd() throws IOException { + final Form form = new Form(); + form.param("name", "Xoel"); + form.param("surname", "Ximénez"); + + final Response response = target("people") + .request(MediaType.APPLICATION_JSON_TYPE) + .post(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE)); + assertOkStatus(response); + + final Person person = response.readEntity(Person.class); + assertEquals(11, person.getId()); + assertEquals("Xoel", person.getName()); + assertEquals("Ximénez", person.getSurname()); + } + + @Test + public void testAddMissingName() throws IOException { + final Form form = new Form(); + form.param("surname", "Ximénez"); + + final Response response = target("people") + .request(MediaType.APPLICATION_JSON_TYPE) + .post(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE)); + + assertBadRequestStatus(response); + } + + @Test + public void testAddMissingSurname() throws IOException { + final Form form = new Form(); + form.param("name", "Xoel"); + + final Response response = target("people") + .request(MediaType.APPLICATION_JSON_TYPE) + .post(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE)); + + assertBadRequestStatus(response); + } + + @Test + public void testModify() throws IOException { + final Form form = new Form(); + form.param("name", "Marta"); + form.param("surname", "Méndez"); + + final Response response = target("people/4") + .request(MediaType.APPLICATION_JSON_TYPE) + .put(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE)); + assertOkStatus(response); + + final Person person = response.readEntity(Person.class); + assertEquals(4, person.getId()); + assertEquals("Marta", person.getName()); + assertEquals("Méndez", person.getSurname()); + } + + @Test + public void testModifyName() throws IOException { + final Form form = new Form(); + form.param("name", "Marta"); + + final Response response = target("people/4") + .request(MediaType.APPLICATION_JSON_TYPE) + .put(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE)); + + assertBadRequestStatus(response); + } + + @Test + public void testModifySurname() throws IOException { + final Form form = new Form(); + form.param("surname", "Méndez"); + + final Response response = target("people/4") + .request(MediaType.APPLICATION_JSON_TYPE) + .put(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE)); + + assertBadRequestStatus(response); + } + + @Test + public void testModifyInvalidId() throws IOException { + final Form form = new Form(); + form.param("name", "Marta"); + form.param("surname", "Méndez"); + + final Response response = target("people/100") + .request(MediaType.APPLICATION_JSON_TYPE) + .put(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE)); + + assertBadRequestStatus(response); + } + + @Test + public void testDelete() throws IOException { + final Response response = target("people/4").request().delete(); + assertOkStatus(response); + + assertEquals(4, (int) response.readEntity(Integer.class)); + } + + @Test + public void testDeleteInvalidId() throws IOException { + assertBadRequestStatus(target("people/100").request().delete()); + } +} diff --git a/src/test/java/es/uvigo/esei/daa/web/PeopleWebTest.java b/src/test/java/es/uvigo/esei/daa/web/PeopleWebTest.java new file mode 100644 index 0000000..b89924f --- /dev/null +++ b/src/test/java/es/uvigo/esei/daa/web/PeopleWebTest.java @@ -0,0 +1,137 @@ +package es.uvigo.esei.daa.web; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.util.concurrent.TimeUnit; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.Cookie; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.firefox.FirefoxDriver; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; + +import es.uvigo.esei.daa.TestUtils; + +public class PeopleWebTest { + private static final int DEFAULT_WAIT_TIME = 1; + private WebDriver driver; + private String baseUrl; + private StringBuffer verificationErrors = new StringBuffer(); + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + TestUtils.createFakeContext(); + } + + @Before + public void setUp() throws Exception { + TestUtils.initTestDatabase(); + + driver = new FirefoxDriver(); + baseUrl = "http://localhost:9080/DAAExample/"; + + driver.get(baseUrl); + driver.manage().addCookie( + new Cookie( + "token", + "25d35467c91f0f8bbcc9a4f22bb359170643ccfdf38851599a03a8ffc0756666" + ) + ); + // Driver will wait DEFAULT_WAIT_TIME if it doesn't find and element. + driver.manage().timeouts().implicitlyWait(DEFAULT_WAIT_TIME, TimeUnit.SECONDS); + + driver.get(baseUrl + "main.html"); + driver.findElement(By.id("people-list")); + } + + @After + public void tearDown() throws Exception { + TestUtils.clearTestDatabase(); + + driver.quit(); + String verificationErrorString = verificationErrors.toString(); + if (!"".equals(verificationErrorString)) { + fail(verificationErrorString); + } + } + + @Test + public void testList() throws Exception { + verifyXpathCount("//tr", 11); + } + + @Test + public void testAdd() throws Exception { + final String name = "Hola"; + final String surname = "Mundo"; + + driver.findElement(By.name("name")).clear(); + driver.findElement(By.name("name")).sendKeys(name); + driver.findElement(By.name("surname")).clear(); + driver.findElement(By.name("surname")).sendKeys(surname); + driver.findElement(By.id("btnSubmit")).click(); + driver.findElement(By.xpath("//td[text()='Hola']")); + + assertEquals(name, + driver.findElement(By.cssSelector("tr:last-child > td.name")).getText() + ); + assertEquals(surname, + driver.findElement(By.cssSelector("tr:last-child > td.surname")).getText() + ); + } + + @Test + public void testEdit() throws Exception { + final String name = "Xián"; + final String surname = "Ximénez"; + + final String trId = driver.findElement(By.xpath("//tr[last()]")).getAttribute("id"); + driver.findElement(By.xpath("//tr[@id='" + trId + "']//a[text()='Edit']")).click(); + driver.findElement(By.name("name")).clear(); + driver.findElement(By.name("name")).sendKeys(name); + driver.findElement(By.name("surname")).clear(); + driver.findElement(By.name("surname")).sendKeys(surname); + driver.findElement(By.id("btnSubmit")).click(); + waitForTextInElement(By.name("name"), ""); + waitForTextInElement(By.name("surname"), ""); + + assertEquals(name, + driver.findElement(By.xpath("//tr[@id='" + trId + "']/td[@class='name']")).getText() + ); + assertEquals(surname, + driver.findElement(By.xpath("//tr[@id='" + trId + "']/td[@class='surname']")).getText() + ); + } + + @Test + public void testDelete() throws Exception { + final String trId = driver.findElement(By.xpath("//tr[last()]")).getAttribute("id"); + driver.findElement(By.xpath("(//a[contains(text(),'Delete')])[last()]")).click(); + driver.switchTo().alert().accept(); + waitUntilNotFindElement(By.id(trId)); + } + + private boolean waitUntilNotFindElement(By by) { + return new WebDriverWait(driver, DEFAULT_WAIT_TIME) + .until(ExpectedConditions.invisibilityOfElementLocated(by)); + } + + private boolean waitForTextInElement(By by, String text) { + return new WebDriverWait(driver, DEFAULT_WAIT_TIME) + .until(ExpectedConditions.textToBePresentInElementLocated(by, text)); + } + + private void verifyXpathCount(String xpath, int count) { + try { + assertEquals(count, driver.findElements(By.xpath(xpath)).size()); + } catch (Error e) { + verificationErrors.append(e.toString()); + } + } +} diff --git a/src/test/webapp/rest/people/add.html b/src/test/webapp/rest/people/add.html new file mode 100644 index 0000000..184475e --- /dev/null +++ b/src/test/webapp/rest/people/add.html @@ -0,0 +1,132 @@ + + + + + + +add + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
add
openchrome://restclient/content/restclient.html
clicklink=Headers
clicklink=Custom Header
typename=nameCookie
typename=valuetoken=25d35467c91f0f8bbcc9a4f22bb359170643ccfdf38851599a03a8ffc0756666
clickcss=#modal-custom-header > div.modal-footer > input.btn.btn-inverse
clicklink=Headers
clicklink=Custom Header
typename=nameContent-Type
typename=valueapplication/x-www-form-urlencoded
clickcss=#modal-custom-header > div.modal-footer > input.btn.btn-inverse
typeid=request-bodyname=Xián&surname=Ximénez
clicklink=POST
typeid=request-urlhttp://localhost:9080/DAAExample/rest/people
clickid=request-button
clicklink=×
waitForElementPresentcss=span.header-value
assertTextcss=span.header-value200 OK
waitForElementPresentcss=#response-body-raw > pre
storeTextcss=#response-body-raw > preresponseBody
echo${responseBody}
assertEvalJSON.parse(storedVars['responseBody']).nameXián
assertEvalJSON.parse(storedVars['responseBody']).surnameXiménez
+ + diff --git a/src/test/webapp/rest/people/addNoName.html b/src/test/webapp/rest/people/addNoName.html new file mode 100644 index 0000000..e20f6f6 --- /dev/null +++ b/src/test/webapp/rest/people/addNoName.html @@ -0,0 +1,107 @@ + + + + + + +addNoName + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
addNoName
openchrome://restclient/content/restclient.html
clicklink=Headers
clicklink=Custom Header
typename=nameCookie
typename=valuetoken=25d35467c91f0f8bbcc9a4f22bb359170643ccfdf38851599a03a8ffc0756666
clickcss=#modal-custom-header > div.modal-footer > input.btn.btn-inverse
clicklink=Headers
clicklink=Custom Header
typename=nameContent-Type
typename=valueapplication/x-www-form-urlencoded
clickcss=#modal-custom-header > div.modal-footer > input.btn.btn-inverse
typeid=request-bodysurname=Ximénez
clicklink=POST
typeid=request-urlhttp://localhost:9080/DAAExample/rest/people
clickid=request-button
clicklink=×
waitForElementPresentcss=span.header-value
assertTextcss=span.header-value400 Bad Request
+ + diff --git a/src/test/webapp/rest/people/addNoSurname.html b/src/test/webapp/rest/people/addNoSurname.html new file mode 100644 index 0000000..909988c --- /dev/null +++ b/src/test/webapp/rest/people/addNoSurname.html @@ -0,0 +1,107 @@ + + + + + + +addNoSurname + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
addNoSurname
openchrome://restclient/content/restclient.html
clicklink=Headers
clicklink=Custom Header
typename=nameCookie
typename=valuetoken=25d35467c91f0f8bbcc9a4f22bb359170643ccfdf38851599a03a8ffc0756666
clickcss=#modal-custom-header > div.modal-footer > input.btn.btn-inverse
clicklink=Headers
clicklink=Custom Header
typename=nameContent-Type
typename=valueapplication/x-www-form-urlencoded
clickcss=#modal-custom-header > div.modal-footer > input.btn.btn-inverse
typeid=request-bodyname=Xián
clicklink=POST
typeid=request-urlhttp://localhost:9080/DAAExample/rest/people
clickid=request-button
clicklink=×
waitForElementPresentcss=span.header-value
assertTextcss=span.header-value400 Bad Request
+ + diff --git a/src/test/webapp/rest/people/delete.html b/src/test/webapp/rest/people/delete.html new file mode 100644 index 0000000..4e3fe0a --- /dev/null +++ b/src/test/webapp/rest/people/delete.html @@ -0,0 +1,77 @@ + + + + + + +delete + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
delete
openchrome://restclient/content/restclient.html
clicklink=Headers
clicklink=Custom Header
typename=nameCookie
typename=valuetoken=25d35467c91f0f8bbcc9a4f22bb359170643ccfdf38851599a03a8ffc0756666
clickcss=#modal-custom-header > div.modal-footer > input.btn.btn-inverse
clicklink=DELETE
typeid=request-urlhttp://localhost:9080/DAAExample/rest/people/11
clickid=request-button
clicklink=×
waitForElementPresentcss=span.header-value
assertTextcss=span.header-value200 OK
+ + diff --git a/src/test/webapp/rest/people/deleteInvalidId.html b/src/test/webapp/rest/people/deleteInvalidId.html new file mode 100644 index 0000000..0c9fa0d --- /dev/null +++ b/src/test/webapp/rest/people/deleteInvalidId.html @@ -0,0 +1,77 @@ + + + + + + +deleteInvalidId + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
deleteInvalidId
openchrome://restclient/content/restclient.html
clicklink=Headers
clicklink=Custom Header
typename=nameCookie
typename=valuetoken=25d35467c91f0f8bbcc9a4f22bb359170643ccfdf38851599a03a8ffc0756666
clickcss=#modal-custom-header > div.modal-footer > input.btn.btn-inverse
clicklink=DELETE
typeid=request-urlhttp://localhost:9080/DAAExample/rest/people/100
clickid=request-button
clicklink=×
waitForElementPresentcss=span.header-value
assertTextcss=span.header-value400 Bad Request
+ + diff --git a/src/test/webapp/rest/people/get.html b/src/test/webapp/rest/people/get.html new file mode 100644 index 0000000..0e5980f --- /dev/null +++ b/src/test/webapp/rest/people/get.html @@ -0,0 +1,96 @@ + + + + + + +rest + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
rest
openchrome://restclient/content/restclient.html
clicklink=Headers
clicklink=Custom Header
typename=nameCookie
typename=valuetoken=25d35467c91f0f8bbcc9a4f22bb359170643ccfdf38851599a03a8ffc0756666
clickcss=#modal-custom-header > div.modal-footer > input.btn.btn-inverse
clicklink=GET
typeid=request-urlhttp://localhost:9080/DAAExample/rest/people
clickid=request-button
clicklink=×
waitForElementPresentcss=span.header-value
assertTextcss=span.header-value200 OK
waitForElementPresentcss=#response-body-raw > pre
storeTextcss=#response-body-raw > preresponseBody
echo${responseBody}
assertEvalJSON.parse(storedVars['responseBody']).length10
+ + diff --git a/src/test/webapp/rest/people/list.html b/src/test/webapp/rest/people/list.html new file mode 100644 index 0000000..0e5980f --- /dev/null +++ b/src/test/webapp/rest/people/list.html @@ -0,0 +1,96 @@ + + + + + + +rest + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
rest
openchrome://restclient/content/restclient.html
clicklink=Headers
clicklink=Custom Header
typename=nameCookie
typename=valuetoken=25d35467c91f0f8bbcc9a4f22bb359170643ccfdf38851599a03a8ffc0756666
clickcss=#modal-custom-header > div.modal-footer > input.btn.btn-inverse
clicklink=GET
typeid=request-urlhttp://localhost:9080/DAAExample/rest/people
clickid=request-button
clicklink=×
waitForElementPresentcss=span.header-value
assertTextcss=span.header-value200 OK
waitForElementPresentcss=#response-body-raw > pre
storeTextcss=#response-body-raw > preresponseBody
echo${responseBody}
assertEvalJSON.parse(storedVars['responseBody']).length10
+ + diff --git a/src/test/webapp/rest/people/modify.html b/src/test/webapp/rest/people/modify.html new file mode 100644 index 0000000..bd1990c --- /dev/null +++ b/src/test/webapp/rest/people/modify.html @@ -0,0 +1,132 @@ + + + + + + +modify + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
modify
openchrome://restclient/content/restclient.html
clicklink=Headers
clicklink=Custom Header
typename=nameCookie
typename=valuetoken=25d35467c91f0f8bbcc9a4f22bb359170643ccfdf38851599a03a8ffc0756666
clickcss=#modal-custom-header > div.modal-footer > input.btn.btn-inverse
clicklink=Headers
clicklink=Custom Header
typename=nameContent-Type
typename=valueapplication/x-www-form-urlencoded
clickcss=#modal-custom-header > div.modal-footer > input.btn.btn-inverse
typeid=request-bodyname=Marta&surname=Martínez
clicklink=PUT
typeid=request-urlhttp://localhost:9080/DAAExample/rest/people/4
clickid=request-button
clicklink=×
waitForElementPresentcss=span.header-value
assertTextcss=span.header-value200 OK
waitForElementPresentcss=#response-body-raw > pre
storeTextcss=#response-body-raw > preresponseBody
echo${responseBody}
assertEvalJSON.parse(storedVars['responseBody']).nameMarta
assertEvalJSON.parse(storedVars['responseBody']).surnameMartínez
+ + diff --git a/src/test/webapp/rest/people/modifyInvalidId.html b/src/test/webapp/rest/people/modifyInvalidId.html new file mode 100644 index 0000000..41632c4 --- /dev/null +++ b/src/test/webapp/rest/people/modifyInvalidId.html @@ -0,0 +1,107 @@ + + + + + + +modifyInvalidId + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
modifyInvalidId
openchrome://restclient/content/restclient.html
clicklink=Headers
clicklink=Custom Header
typename=nameCookie
typename=valuetoken=25d35467c91f0f8bbcc9a4f22bb359170643ccfdf38851599a03a8ffc0756666
clickcss=#modal-custom-header > div.modal-footer > input.btn.btn-inverse
clicklink=Headers
clicklink=Custom Header
typename=nameContent-Type
typename=valueapplication/x-www-form-urlencoded
clickcss=#modal-custom-header > div.modal-footer > input.btn.btn-inverse
typeid=request-bodyname=Marta&surname=Martínez
clicklink=PUT
typeid=request-urlhttp://localhost:9080/DAAExample/rest/people/100
clickid=request-button
clicklink=×
waitForElementPresentcss=span.header-value
assertTextcss=span.header-value400 Bad Request
+ + diff --git a/src/test/webapp/rest/people/modifyNoId.html b/src/test/webapp/rest/people/modifyNoId.html new file mode 100644 index 0000000..843ae72 --- /dev/null +++ b/src/test/webapp/rest/people/modifyNoId.html @@ -0,0 +1,107 @@ + + + + + + +modifyNoId + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
modifyNoId
openchrome://restclient/content/restclient.html
clicklink=Headers
clicklink=Custom Header
typename=nameCookie
typename=valuetoken=25d35467c91f0f8bbcc9a4f22bb359170643ccfdf38851599a03a8ffc0756666
clickcss=#modal-custom-header > div.modal-footer > input.btn.btn-inverse
clicklink=Headers
clicklink=Custom Header
typename=nameContent-Type
typename=valueapplication/x-www-form-urlencoded
clickcss=#modal-custom-header > div.modal-footer > input.btn.btn-inverse
typeid=request-bodyname=Marta&surname=Martínez
clicklink=PUT
typeid=request-urlhttp://localhost:9080/DAAExample/rest/people
clickid=request-button
clicklink=×
waitForElementPresentcss=span.header-value
assertTextcss=span.header-value405 Method Not Allowed
+ + diff --git a/src/test/webapp/rest/people/modifyNoName.html b/src/test/webapp/rest/people/modifyNoName.html new file mode 100644 index 0000000..ca43e00 --- /dev/null +++ b/src/test/webapp/rest/people/modifyNoName.html @@ -0,0 +1,107 @@ + + + + + + +modifyNoName + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
modifyNoName
openchrome://restclient/content/restclient.html
clicklink=Headers
clicklink=Custom Header
typename=nameCookie
typename=valuetoken=25d35467c91f0f8bbcc9a4f22bb359170643ccfdf38851599a03a8ffc0756666
clickcss=#modal-custom-header > div.modal-footer > input.btn.btn-inverse
clicklink=Headers
clicklink=Custom Header
typename=nameContent-Type
typename=valueapplication/x-www-form-urlencoded
clickcss=#modal-custom-header > div.modal-footer > input.btn.btn-inverse
typeid=request-bodysurname=Martínez
clicklink=PUT
typeid=request-urlhttp://localhost:9080/DAAExample/rest/people/4
clickid=request-button
clicklink=×
waitForElementPresentcss=span.header-value
assertTextcss=span.header-value400 Bad Request
+ + diff --git a/src/test/webapp/rest/people/modifyNoSurname.html b/src/test/webapp/rest/people/modifyNoSurname.html new file mode 100644 index 0000000..25caa0f --- /dev/null +++ b/src/test/webapp/rest/people/modifyNoSurname.html @@ -0,0 +1,107 @@ + + + + + + +modifyNoSurname + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
modifyNoSurname
openchrome://restclient/content/restclient.html
clicklink=Headers
clicklink=Custom Header
typename=nameCookie
typename=valuetoken=25d35467c91f0f8bbcc9a4f22bb359170643ccfdf38851599a03a8ffc0756666
clickcss=#modal-custom-header > div.modal-footer > input.btn.btn-inverse
clicklink=Headers
clicklink=Custom Header
typename=nameContent-Type
typename=valueapplication/x-www-form-urlencoded
clickcss=#modal-custom-header > div.modal-footer > input.btn.btn-inverse
typeid=request-bodyname=Marta
clicklink=PUT
typeid=request-urlhttp://localhost:9080/DAAExample/rest/people/4
clickid=request-button
clicklink=×
waitForElementPresentcss=span.header-value
assertTextcss=span.header-value400 Bad Request
+ + diff --git a/src/test/webapp/rest/people/rest.html b/src/test/webapp/rest/people/rest.html new file mode 100644 index 0000000..4dd4a50 --- /dev/null +++ b/src/test/webapp/rest/people/rest.html @@ -0,0 +1,24 @@ + + + + + + Test Suite + + + + + + + + + + + + + + + +
Test Suite
list
add
addNoName
addNoSurname
modify
modifyInvalidId
modifyNoId
modifyNoName
modifyNoSurname
delete
deleteInvalidId
+ + diff --git a/src/test/webapp/web/people/add.html b/src/test/webapp/web/people/add.html new file mode 100644 index 0000000..7ea2c1e --- /dev/null +++ b/src/test/webapp/web/people/add.html @@ -0,0 +1,71 @@ + + + + + + +example + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
example
createCookietoken=25d35467c91f0f8bbcc9a4f22bb359170643ccfdf38851599a03a8ffc0756666
openmain.html
waitForPageToLoad
waitForConditionselenium.browserbot.getCurrentWindow().jQuery.active == 01000
typename=nameHola
typename=surnameMundo
clickid=btnSubmit
waitForConditionselenium.browserbot.getCurrentWindow().jQuery.active == 01000
verifyTextcss=tr:last-child > td.nameHola
verifyTextcss=tr:last-child > td.surnameMundo
deleteCookietoken
+ + diff --git a/src/test/webapp/web/people/delete.html b/src/test/webapp/web/people/delete.html new file mode 100644 index 0000000..7155a2f --- /dev/null +++ b/src/test/webapp/web/people/delete.html @@ -0,0 +1,76 @@ + + + + + + +delete + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
delete
createCookietoken=25d35467c91f0f8bbcc9a4f22bb359170643ccfdf38851599a03a8ffc0756666
openmain.html
waitForPageToLoad
waitForConditionselenium.browserbot.getCurrentWindow().jQuery.active == 01000
storeXpathCount//trrows
clickxpath=(//a[contains(text(),'Delete')])[last()]
assertConfirmationEstá a punto de eliminar a una persona. ¿Está seguro de que desea continuar?
waitForConditionselenium.browserbot.getCurrentWindow().jQuery.active == 01000
storeXpathCount//trrowsAfterDeletion
storeEvalstoredVars['rows']-storedVars['rowsAfterDeletion']rowsDeleted
verifyExpression${rowsDeleted}1
deleteCookietoken
+ + diff --git a/src/test/webapp/web/people/edit.html b/src/test/webapp/web/people/edit.html new file mode 100644 index 0000000..b513e26 --- /dev/null +++ b/src/test/webapp/web/people/edit.html @@ -0,0 +1,82 @@ + + + + + + +edit + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
edit
createCookietoken=25d35467c91f0f8bbcc9a4f22bb359170643ccfdf38851599a03a8ffc0756666
openmain.html
waitForPageToLoad
waitForConditionselenium.browserbot.getCurrentWindow().jQuery.active == 01000
clickxpath=(//a[contains(text(),'Edit')])[last()]
storeAttribute//tr[last()]/@idpersonId
typename=nameAna
typename=surnameMaría
clickid=btnSubmit
waitForConditionselenium.browserbot.getCurrentWindow().jQuery.active == 01000
verifyText//tr[@id='${personId}']/td[@class = 'name']Ana
verifyText//tr[@id='${personId}']/td[@class = 'surname']María
deleteCookietoken
+ + diff --git a/src/test/webapp/web/people/example.html b/src/test/webapp/web/people/example.html new file mode 100644 index 0000000..e1dbb63 --- /dev/null +++ b/src/test/webapp/web/people/example.html @@ -0,0 +1,17 @@ + + + + + + Test Suite + + + + + + + + +
Test Suite
list
add
edit
delete
+ + diff --git a/src/test/webapp/web/people/list.html b/src/test/webapp/web/people/list.html new file mode 100644 index 0000000..8845d96 --- /dev/null +++ b/src/test/webapp/web/people/list.html @@ -0,0 +1,46 @@ + + + + + + +list + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
list
createCookietoken=25d35467c91f0f8bbcc9a4f22bb359170643ccfdf38851599a03a8ffc0756666
openmain.html
waitForPageToLoad
waitForConditionselenium.browserbot.getCurrentWindow().jQuery.active == 01000
verifyXpathCount//tr11
deleteCookietoken
+ + -- 2.18.1