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);
}
}