Skip to content

Commit

Permalink
#1022 - Apply Automation test for Yas project
Browse files Browse the repository at this point in the history
- Update create product scenario
  • Loading branch information
Duy Le Van committed Sep 23, 2024
1 parent 0515ca7 commit faf9e16
Show file tree
Hide file tree
Showing 7 changed files with 298 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;
import java.util.function.Supplier;

/**
* BasePage provides common setup for web pages in the automation framework.
Expand Down Expand Up @@ -50,6 +51,14 @@ public void scrollTo(WebElement webElement) {
wait(Duration.ofSeconds(1));
}

public boolean isElementPresent(Supplier<WebElement> webElementConsumer) {
try {
return webElementConsumer.get().isDisplayed();
} catch (Exception exception) {
return false;
}
}

public WebDriver getWebDriver() {
return webDriverFactory.getChromeDriver();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.yas.automation.ui.enumerate;

public enum ProductAttribute {
CPU,
GPU,
OS,
SCREEN_SIZE,
PANEL,
BLUETOOTH,
NFC,
MAIN_CAMERA,
SUB_CAMERA,
RAM,
STORAGE,
SCREEN_RESOLUTION;

public static final String BASE_XPATH = "//*[@class=\"fade tab-pane active show\"]/table/tbody/tr[%s]/th[2]/input";
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package com.yas.automation.ui;

import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
import io.cucumber.testng.AbstractTestNGCucumberTests;
import io.cucumber.testng.CucumberOptions;
import org.junit.runner.RunWith;
import org.testng.annotations.DataProvider;

@RunWith(Cucumber.class)
@CucumberOptions(
features = "src/test/resources/features/createCategory.feature",
features = "src/test/resources/features",
glue = "com.yas.automation.ui"
)
public class JUnitCucumberRunner extends AbstractTestNGCucumberTests {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ public class ProductForm extends BaseForm {
@FindBy(how = How.ID, using = "name")
private WebElement name;

@FindBy(how = How.ID, using = "slug")
private WebElement slug;

@FindBy(how = How.ID, using = "price")
private WebElement price;

Expand All @@ -37,18 +40,102 @@ public class ProductForm extends BaseForm {
@FindBy(id = "shortDescription")
private WebElement shortDescription;

@FindBy(id = "react-select-2-input")
private WebElement productVariationAvailableOption;

@FindBy(id = "react-select-2-listbox")
private WebElement productVariationAvailableOptionListBox;

@FindBy(id = "RAM")
private WebElement ram;

@FindBy(how = How.NAME, using = "optionPrice")
private WebElement ramOptionPrice;

@FindBy(how = How.NAME, using = "optionGtin")
private WebElement ramOptionGtin;

@FindBy(how = How.NAME, using = "optionSku")
private WebElement ramOptionSku;

@FindBy(id = "sub-thumbnail-0")
private WebElement ramThumbnail;

@FindBy(id = "sub-images-0")
private WebElement productSubImage;

@FindBy(xpath = "//button[@type='submit' and contains(text(),'Create')]")
private WebElement createBtn;

@FindBy(xpath = "//button[@type='button' and contains(text(),'Product Attributes')]")
private WebElement productAttributeNav;

@FindBy(xpath = "//button[@type='button' and contains(text(),'Category Mapping')]")
private WebElement categoryMappingNav;

@FindBy(xpath = "//button[@type='button' and contains(text(),'Cross-sell Product')]")
private WebElement crossSellProductNav;

@FindBy(xpath = "//button[@type='button' and contains(text(),'SEO')]")
private WebElement seoNav;

@FindBy(id = "metaTitle")
private WebElement seoMetaTitle;

@FindBy(id = "metaKeyword")
private WebElement seoMetaKeyword;

@FindBy(id = "metaDescription")
private WebElement seoMetaDescription;

@FindBy(xpath = "//button[contains(text(),'Manage Cross-Sell Product')]")
private WebElement managedCrossSellProductBtn;

@FindBy(xpath = "//button[contains(text(),'Apply')]")
private WebElement productTemplateApplyButton;

@FindBy(id = "product-template")
private WebElement productTemplate;

@FindBy(id = "attribute")
private WebElement productTemplateAvailableAttribute;

@FindBy(id = "iphone-15-pro-max")
private WebElement ip15ChkBox;

@FindBy(xpath = "//button[@type='button' and contains(text(),'Product Images')]")
private WebElement productImgNav;

@FindBy(xpath = "//button[@type='button' and contains(text(),'Product Variations')]")
private WebElement productVariantsNav;

@FindBy(xpath = "//button[@type='button' and contains(text(),'Related Products')]")
private WebElement relatedProductNav;

@FindBy(xpath = "//button[@type='button' and contains(text(),'Add Related Product')]")
private WebElement relatedProductAddBtn;

@FindBy(xpath = "//button[@type='button' and contains(text(),'Close')]")
private WebElement modalCloseBtn;

@FindBy(xpath = "//button[contains(text(),'Add Option')]")
private WebElement addOptionBtn;

@FindBy(xpath = "//button[contains(text(),'Create')]")
private WebElement productAttributeCreateBtn;

@FindBy(xpath = "//button[contains(text(),'Generate Combine')]")
private WebElement generateCombinationBtn;

@FindBy(how = How.ID, using = "main-thumbnail")
private WebElement thumbnail;

@FindBy(how = How.ID, using = "main-product-images")
private WebElement image;

@FindBy(id = "checkbox-5")
private WebElement catMappingLaptopChkBox;

public ProductForm(WebDriver webDriver) {
super(webDriver);
PageFactory.initElements(webDriver, this);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,35 @@
package com.yas.automation.ui.pages;

import com.yas.automation.ui.enumerate.ProductAttribute;
import com.yas.automation.ui.form.InputType;
import com.yas.automation.ui.form.ProductForm;
import com.yas.automation.ui.hook.WebDriverFactory;
import com.yas.automation.ui.page.BasePage;
import com.yas.automation.ui.service.InputDelegateService;
import com.yas.automation.ui.util.WebElementUtil;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.How;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.springframework.stereotype.Component;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

import static com.yas.automation.ui.enumerate.ProductAttribute.BASE_XPATH;
import static com.yas.automation.ui.util.WebElementUtil.getWebElementBy;
import static org.junit.Assert.assertTrue;

@Component
public class ProductPage extends BasePage {

public static final int NUM_OF_TABLE_ROW = 6;
public static final int NUM_OF_DEFAULT_ATTRIBUTE = 7;
public static final String SAMPLE_TEMPLATE = "Sample Template";
public static final String DUMP_FILE_PATH = "sampledata/images/dell.jpg";

private final WebDriverFactory webDriverFactory;
private final InputDelegateService inputDelegateService;

Expand Down Expand Up @@ -57,9 +67,150 @@ public void uploadProductImg(ProductForm productForm) {
this.wait(Duration.ofSeconds(2));
productForm.getProductImgNav().click();

String filePath = "sampledata/images/dell.jpg";
inputDelegateService.setInputValue(InputType.FILE, productForm.getImage(), filePath);
inputDelegateService.setInputValue(InputType.FILE, productForm.getThumbnail(), filePath);
inputDelegateService.setInputValue(InputType.FILE, productForm.getImage(), DUMP_FILE_PATH);
boolean isProductImgPreviewVisible = isElementPresent(
() -> WebElementUtil.getWebElementBy(
webDriverFactory.getChromeDriver(),
How.XPATH,
"//img[@alt='Image']")
);
assertTrue("Product Image preview must be visible", isProductImgPreviewVisible);

inputDelegateService.setInputValue(InputType.FILE, productForm.getThumbnail(), DUMP_FILE_PATH);
boolean isThumbnailPreviewVisible = isElementPresent(
() -> WebElementUtil.getWebElementBy(
webDriverFactory.getChromeDriver(),
How.XPATH,
"//img[@alt='Thumbnail']")
);
assertTrue("Thumbnail preview must be visible", isThumbnailPreviewVisible);
}

public void fillProductVariants(ProductForm productForm) {
scrollTo(productForm.getProductVariantsNav());
productForm.getProductVariantsNav().click();

// Select available options
inputDelegateService.setInputValue(InputType.TEXT, productForm.getProductVariationAvailableOption(), "RAM");
productForm.getProductVariationAvailableOptionListBox().click();

// Add Option
productForm.getAddOptionBtn().click();
inputDelegateService.setInputValue(InputType.TEXT, productForm.getRam(), "32GB");

// Add combination
productForm.getGenerateCombinationBtn().click();
inputDelegateService.setInputValue(InputType.TEXT, productForm.getRamOptionPrice(), "2000000");
inputDelegateService.setInputValue(InputType.TEXT, productForm.getRamOptionGtin(), UUID.randomUUID().toString());
inputDelegateService.setInputValue(InputType.TEXT, productForm.getRamOptionSku(), UUID.randomUUID().toString());

// Add combination images
inputDelegateService.setInputValue(InputType.FILE, productForm.getRamThumbnail(), DUMP_FILE_PATH);
inputDelegateService.setInputValue(InputType.FILE, productForm.getProductSubImage(), DUMP_FILE_PATH);
}

public void fillProductAttribute(ProductForm productForm) {
scrollTo(productForm.getProductAttributeNav());
productForm.getProductAttributeNav().click();

inputDelegateService.setInputValue(InputType.DROPDOWN, productForm.getProductTemplate(), SAMPLE_TEMPLATE);
inputDelegateService.setInputValue(
InputType.DROPDOWN,
productForm.getProductTemplateAvailableAttribute(),
ProductAttribute.CPU.toString()
);
productForm.getProductTemplateApplyButton().click();

// Add product attributes
for (int i = 1; i < NUM_OF_DEFAULT_ATTRIBUTE; i++) {
WebElementUtil.getWebElementBy(
webDriverFactory.getChromeDriver(),
How.XPATH,
BASE_XPATH.formatted(i)
).sendKeys(UUID.randomUUID().toString());
}
scrollTo(productForm.getProductAttributeCreateBtn());
}

public void fillCategoryMapping(ProductForm productForm) {
scrollTo(productForm.getCategoryMappingNav());
productForm.getCategoryMappingNav().click();
inputDelegateService.setInputValue(InputType.CHECKBOX, productForm.getCatMappingLaptopChkBox(), null);
}

public void fillRelatedProduct(ProductForm productForm) {
scrollTo(productForm.getRelatedProductNav());
productForm.getRelatedProductNav().click();
productForm.getRelatedProductAddBtn().click();
getFirstCheckBoxElementInModalList("//*/table/tbody/tr[1]/td[1]").click();
productForm.getModalCloseBtn().click();
}

private WebElement getFirstCheckBoxElementInModalList(String identity) {
return WebElementUtil.getWebElementBy(
webDriverFactory.getChromeDriver(),
How.XPATH,
identity

).findElement(By.cssSelector("input[type='checkbox'].form-check-input"));
}

public void fillCrossSellProduct(ProductForm productForm) {
scrollTo(productForm.getCrossSellProductNav());
productForm.getCrossSellProductNav().click();
productForm.getManagedCrossSellProductBtn().click();
getFirstCheckBoxElementInModalList("/html/body/div[3]/div/div/div[2]/table/tbody/tr[1]/td[1]").click();
productForm.getModalCloseBtn().click();
}

public void fillSEOProduct(ProductForm productForm) {
scrollTo(productForm.getSeoNav());
productForm.getSeoNav().click();
inputDelegateService.setInputValue(InputType.TEXT, productForm.getSeoMetaTitle(), UUID.randomUUID().toString());
inputDelegateService.setInputValue(InputType.TEXT, productForm.getSeoMetaKeyword(), UUID.randomUUID().toString());
inputDelegateService.setInputValue(InputType.TEXT, productForm.getSeoMetaDescription(), UUID.randomUUID().toString());
}

/**
* This method used to look up all pages until we find the created product.
* Currently, It does not show at first page, as sample data lack of lastModified field
* (product list is order by lastModified desc then sample data always on top pages)
* @param newProductName productName which we look for
* @return is the new product show in all pages or not.
*/
public boolean isNewProductShow(String newProductName) {
final WebDriver chromeDriver = webDriverFactory.getChromeDriver();
WebElement paginationBar = getWebElementBy(
chromeDriver,
How.CLASS_NAME,
"pagination-container"
);
List<WebElement> pageItems = paginationBar.findElements(By.tagName("li"));

// pageItems.size() - 2 >> is to skip "Next" link
/*
* for example: 1 2 3 ... 12 Next
* >> try to get '12'
*/
int totalPage = pageItems.isEmpty() ? 0 : Integer.parseInt(pageItems.get(pageItems.size() - 2).getText());
final String baseProductItemXPath = "//*/table/tbody/tr[%s]/td[2]";
int currentPage = 1;
while (currentPage < totalPage) {
// check all rows in table
for (int i = 1; i < NUM_OF_TABLE_ROW; i++) {
WebElement productName = getWebElementBy(
chromeDriver,
How.XPATH,
baseProductItemXPath.formatted(i)
);
if (Objects.equals(newProductName, productName.getText())) {
return true;
}
}
currentPage++;
getWebElementBy(chromeDriver, How.LINK_TEXT, String.valueOf(currentPage)).click(); // next page
}
return false;
}

}
Loading

0 comments on commit faf9e16

Please sign in to comment.