package org.jboss.as.quickstarts.datagrid.carmart; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.drone.api.annotation.Drone; import org.jboss.arquillian.graphene.findby.FindByJQuery; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; import org.openqa.selenium.NoSuchElementException; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import java.net.URL; import static org.jboss.arquillian.graphene.Graphene.waitModel; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertFalse; import static org.junit.Assert.fail; /** * Test for CarMart example using Drone Arquillian extension and Graphenebrowser framework for testing app UI * * Scenario (only basic operations): * Start CarMart, try to add new car, check if new car is added, try to remove added car, check if car was successfully removed * + verify transaction rollback - car is not added into cache (see comment in code for details) * * @author tsykora@redhat.com * @author jholusa@redhat.com */ @RunWith(Arquillian.class) @RunAsClient public class CarmartTxTest { @FindBy(id = "j_idt6") private WebElement FORM_ID; @FindByJQuery(":contains('JDG Transactional CarMart')") private WebElement welcomeCarmart; @FindByJQuery("a:contains('New car')") private WebElement newCarLink; @FindByJQuery("#j_idt6:contains('Add a new car to the Car Mart')") private WebElement addNewCar; @FindByJQuery("#j_idt6:contains('List of available cars')") private WebElement listOfCars; @FindByJQuery("#j_idt6:contains('Number Plate')") private WebElement numberPlateLabel; @FindByJQuery(":input[type=text]:eq(0)") private WebElement numberPlateInput; @FindByJQuery(":input[type=text]:eq(1)") private WebElement brandInput; @FindByJQuery(":input[type=text]:eq(2)") private WebElement colorInput; @FindByJQuery(":input[type=text]:eq(3)") private WebElement displacementInput; @FindByJQuery("table:eq(1) tr:eq(1) td:eq(1)") private WebElement storesCountElement; @FindByJQuery(":submit") private WebElement submitCarButton; @FindByJQuery(":contains('1B2 1234')") private WebElement addedCar; @FindByJQuery("a:contains('View'):eq(5)") private WebElement viewAddedCar; @FindByJQuery(":contains('1B2 1234')") private WebElement numberPlateInputAdded; @FindByJQuery(":contains('TOYOTA')") private WebElement brandInputAdded; @FindByJQuery(":contains('YELLOW')") private WebElement colorInputAdded; @FindByJQuery(":contains('15')") private WebElement displacementInputAdded; @FindByJQuery("a:contains('Remove'):eq(5)") private WebElement removeAddedCar; @FindByJQuery("a:contains('Home')") private WebElement homeLink; @FindByJQuery("input[type=\"submit\"][value=\"Add car with rollback\"]") private WebElement submitRollbackCarButton; @FindByJQuery(":contains('2B3 2345')") private WebElement addedCarTx; @Drone WebDriver browser; @ArquillianResource private URL contextPath; @Deployment(testable = false) public static WebArchive createTestDeploymentRemote() { return Deployments.createDeploymentTx(); } @Test public void basicOperationsTest() { browser.get(contextPath.toExternalForm()); System.out.println("Inside basicOperationsTest, contextPath: " + contextPath); waitModel().until().element(FORM_ID).is().present(); assertTrue("FORM_ID element is not present", FORM_ID.isDisplayed()); waitModel().until().element(welcomeCarmart).is().present(); assertTrue("welcomeCarmart is not present", welcomeCarmart.isDisplayed()); waitModel().until().element(newCarLink).is().present(); assertTrue("newCarLink is not present", newCarLink.isDisplayed()); newCarLink.click(); waitModel().until().element(addNewCar).is().present(); waitModel().until().element(numberPlateLabel).is().present(); assertTrue("numberPlateLabel is not present", numberPlateLabel.isDisplayed()); waitModel().until().element(numberPlateInput).is().present(); waitModel().until().element(brandInput).is().present(); waitModel().until().element(colorInput).is().present(); waitModel().until().element(displacementInput).is().present(); assertTrue("numberPlateInput is not present", numberPlateInput.isDisplayed()); assertTrue("brandInput is not present", brandInput.isDisplayed()); assertTrue("colorInput is not present", colorInput.isDisplayed()); assertTrue("displacementInput is not present", displacementInput.isDisplayed()); numberPlateInput.sendKeys("1B2 1234"); brandInput.sendKeys("TOYOTA"); colorInput.sendKeys("YELLOW"); displacementInput.sendKeys("15"); // statistic table waitModel().until().element(storesCountElement).is().present(); String storesCountBefore = storesCountElement.getText(); // select all elements of type submit - here only one waitModel().until().element(submitCarButton).is().present(); assertTrue("submitCarButton is not present", submitCarButton.isDisplayed()); submitCarButton.click(); // looking for new car waitModel().until().element(listOfCars).is().present(); // see CarManager class for details (only 1 put there) waitModel().until().element(storesCountElement).is().present(); String storesCountAfter = storesCountElement.getText(); // !!! - the difference must be 2 because in CarmartTx quickstart // there is extra put with number of plates in the same cache, therefore // the number of stores is increased by 1 for inserting car and 1 for inserting this extra info !!! assertTrue("Number of stores after rollback should increase exactly by 2 (because of " + "extra put of number of cars' plates. Not by more or less.", Integer.valueOf(storesCountAfter).equals(Integer.valueOf(storesCountBefore) + 2)); // the 6th view link should be new added car waitModel().until().element(viewAddedCar).is().present(); assertTrue("6th view link for new addedCar is not present", viewAddedCar.isDisplayed()); // show car info viewAddedCar.click(); waitModel().until().element(addedCar).is().present(); waitModel().until().element(numberPlateInputAdded).is().present(); waitModel().until().element(brandInputAdded).is().present(); waitModel().until().element(colorInputAdded).is().present(); waitModel().until().element(displacementInputAdded).is().present(); assertTrue("numberPlateInputAdded is not present....", numberPlateInputAdded.isDisplayed()); assertTrue("brandInputAdded is not present....", brandInputAdded.isDisplayed()); assertTrue("colorInputAdded is not present....", colorInputAdded.isDisplayed()); assertTrue("displacementInputAdded is not present....", displacementInputAdded.isDisplayed()); // back to home page and remove it waitModel().until().element(homeLink).is().present(); homeLink.click(); waitModel().until().element(removeAddedCar).is().present(); assertTrue("6th remove link for new addedCar is not present", removeAddedCar.isDisplayed()); // remove car removeAddedCar.click(); // check if removed try { boolean isDisplayed = viewAddedCar.isDisplayed(); fail("6th view link for new addedCar is STILL present! Should not be!"); } catch(NoSuchElementException ex) { //OK - expected } // verify transaction rollback: // after add with rollback car is not added to the carcache (is rollbacked) // but number of stores is increased by 1 carCache.put(CAR_NUMBERS_KEY, carNumbers); // without rollback number of stores is increase by 2 (new car in cache and update of CAR_NUMBERS_KEY key) waitModel().until().element(newCarLink).is().present(); newCarLink.click(); waitModel().until().element(addNewCar).is().present(); waitModel().until().element(numberPlateLabel).is().present(); assertTrue("numberPlateLabel is not present", numberPlateLabel.isDisplayed()); waitModel().until().element(numberPlateInput).is().present(); waitModel().until().element(brandInput).is().present(); waitModel().until().element(colorInput).is().present(); waitModel().until().element(displacementInput).is().present(); assertTrue("numberPlateInput is not present", numberPlateInput.isDisplayed()); assertTrue("brandInput is not present", brandInput.isDisplayed()); assertTrue("colorInput is not present", colorInput.isDisplayed()); assertTrue("displacementInput is not present", displacementInput.isDisplayed()); numberPlateInput.sendKeys("2B3 2345"); brandInput.sendKeys("MERCEDES"); colorInput.sendKeys("RED"); displacementInput.sendKeys("3"); // statistic table storesCountBefore = storesCountElement.getText(); // select rollback button waitModel().until().element(submitRollbackCarButton).is().present(); assertTrue("submitRollbackCarButton is not present", submitRollbackCarButton.isDisplayed()); submitRollbackCarButton.click(); waitModel().until().element(FORM_ID).is().present(); try { boolean isDisplayed = addedCarTx.isDisplayed(); fail("Rollback was running - car should not be added!"); } catch(NoSuchElementException ex) { //OK - expected! } storesCountAfter = storesCountElement.getText(); assertTrue("Number of stores after rollback should increase exactly by 1. Not by more or less.", Integer.valueOf(storesCountAfter).compareTo(Integer.valueOf(storesCountBefore) + 1) == 0); } }