Commit 631656f9 authored by Trình Nguyễn's avatar Trình Nguyễn

relace

parent 972bdd3b
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="$PROJECT_DIR$/automation_selenium" vcs="Git" /> <mapping directory="$PROJECT_DIR$/automation_selenium" vcs="Git" />
<mapping directory="$PROJECT_DIR$/automation_selenium/LSP_AUTOMATION/automation_selenium" vcs="Git" />
</component> </component>
</project> </project>
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -17,7 +17,11 @@ public class DriverManager { ...@@ -17,7 +17,11 @@ public class DriverManager {
} }
public static void quit() { public static void quit() {
DriverManager.driver.get().quit(); WebDriver webDriver = driver.get();
driver.remove(); if (webDriver != null) {
webDriver.quit();
driver.remove(); // Xóa khỏi ThreadLocal
} }
}
} }
...@@ -2,41 +2,62 @@ package trinhQC.com.helpers; ...@@ -2,41 +2,62 @@ package trinhQC.com.helpers;
import org.openqa.selenium.OutputType; import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot; import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.io.FileHandler;
import org.testng.ITestResult; import org.testng.ITestResult;
import org.testng.Reporter; import org.testng.Reporter;
import trinhQC.com.drivers.DriverManager; import trinhQC.com.drivers.DriverManager;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
public class CaptureHelper { public class CaptureHelper {
//Lấy đường dẫn đến project hiện tại private static final String CAPTURE_PATH = PropertiesHelper.getValue("exportCapturePath");
static String projectPath = System.getProperty("user.dir") + "/"; private static final Path PROJECT_PATH = Path.of(System.getProperty("user.dir"));
//Tạo format ngày giờ để xíu gắn dô cái name của screenshot hoặc record video private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd-MM-yyyy_HH-mm-ss");
private static SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH-mm-ss");
/**
* Capture screenshot when test fails (called from listener)
*/
public static void captureScreenshot(ITestResult result) { public static void captureScreenshot(ITestResult result) {
PropertiesHelper.setDefaultFile(); if (DriverManager.getDriver() == null) {
System.out.println("⚠ Driver is null, cannot capture screenshot.");
return;
}
try { try {
Reporter.log("Driver for Screenshot: " + DriverManager.getDriver()); File screenshot = ((TakesScreenshot) DriverManager.getDriver()).getScreenshotAs(OutputType.FILE);
// Tạo tham chiếu đối tượng của TakesScreenshot với dirver hiện tại Path savePath = getScreenshotPath(result.getName());
TakesScreenshot ts = (TakesScreenshot) DriverManager.getDriver();
// Gọi hàm getScreenshotAs để chuyển hóa hình ảnh về dạng FILE ensureDirectoryExists(savePath.getParent());
File source = ts.getScreenshotAs(OutputType.FILE); Files.copy(screenshot.toPath(), savePath);
//Kiểm tra folder nếu không tồn tại thì tạo folder
File theDir = new File(projectPath + PropertiesHelper.getValue("exportCapturePath")); System.out.println("📸 Screenshot taken: " + savePath);
if (!theDir.exists()){ Reporter.log("📍 Screenshot captured at URL: " + DriverManager.getDriver().getCurrentUrl(), true);
theDir.mkdirs();
} catch (IOException e) {
System.out.println("❌ Failed to take screenshot: " + e.getMessage());
} }
// Chổ này đặt tên thì truyền biến "screenName" gán cho tên File chụp màn hình }
FileHandler.copy(source, new File(projectPath + PropertiesHelper.getValue("exportCapturePath") + "/" + result.getName() + "_" + dateFormat.format(new Date()) + ".png"));
System.out.println("Screenshot taken: " + result.getName()); /**
Reporter.log("Screenshot taken current URL: " + DriverManager.getDriver().getCurrentUrl(), true); * Build screenshot file path with timestamp
} catch (Exception e) { */
System.out.println("Exception while taking screenshot: " + e.getMessage()); private static Path getScreenshotPath(String testName) {
String timestamp = DATE_FORMAT.format(new Date());
String fileName = testName + "_" + timestamp + ".png";
return PROJECT_PATH.resolve(CAPTURE_PATH).resolve(fileName);
}
/**
* Ensure folder exists before saving screenshot
*/
private static void ensureDirectoryExists(Path dir) throws IOException {
if (!Files.exists(dir)) {
Files.createDirectories(dir);
} }
} }
......
package trinhQC.com.helpers; package trinhQC.com.helpers;
import java.nio.file.Path;
public class PathToProject { public class PathToProject {
/**
* Lấy thư mục gốc của project (absolute path)
*/
public static String getCurrentDir() { public static String getCurrentDir() {
String current = System.getProperty("user.dir") + "/"; return Path.of(System.getProperty("user.dir")).toAbsolutePath().toString();
return current;
} }
public static String relPropertiesFilePathDefault(){ /**
String Path = "src/main/java/Main_HRM_AnhTester/DataTest/Properties/Data.properties"; * Đường dẫn tương đối đến file Data.properties
return Path; */
public static String relPropertiesFilePathDefault() {
return Path.of("src", "main", "resources", "Data.properties").toString();
} }
}
/**
* Đường dẫn tuyệt đối đến file Data.properties
*/
public static String getAbsolutePropertiesPath() {
return Path.of(getCurrentDir(), "src", "main", "resources", "Data.properties").toString();
}
}
package trinhQC.com.helpers; package trinhQC.com.helpers;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.LinkedList;
import java.util.Properties; import java.util.Properties;
public class PropertiesHelper { public class PropertiesHelper {
private static Properties properties; private static Properties properties = new Properties();
private static String linkFile; private static String linkFile;
private static FileInputStream file;
private static FileOutputStream out;
private static final String relPropertiesFilePathDefault = "src/main/java/Main_HRM_AnhTester/DataTest/Properties/Data.properties";
public static Properties loadAllFiles() {
LinkedList<String> files = new LinkedList<>();
// Add tất cả file Properties vào đây theo mẫu
files.add("src/main/java/Main_HRM_AnhTester/DataTest/Properties/Data.properties");
try {
properties = new Properties();
for (String f : files) { /**
Properties tempProp = new Properties(); * Load file properties mặc định (src/main/resources/Data.properties)
linkFile = PathToProject.getCurrentDir() + f; */
file = new FileInputStream(linkFile); public static void setDefaultFile() {
tempProp.load(file); linkFile = PathToProject.getAbsolutePropertiesPath();
properties.putAll(tempProp); loadFile(linkFile);
}
return properties;
} catch (IOException ioe) {
return new Properties();
}
} }
public static void setFile(String relPropertiesFilePath) { /**
properties = new Properties(); * Load 1 file properties chỉ định theo đường dẫn tương đối
try { */
linkFile = PathToProject.getCurrentDir() + relPropertiesFilePath; public static void setFile(String relPath) {
file = new FileInputStream(linkFile); linkFile = PathToProject.getCurrentDir() + "/" + relPath;
properties.load(file); loadFile(linkFile);
file.close();
} catch (Exception e) {
e.printStackTrace();
}
} }
public static void setDefaultFile() { /**
properties = new Properties(); * Hàm load nội dung từ file properties
try { */
linkFile = PathToProject.getCurrentDir() + relPropertiesFilePathDefault; private static void loadFile(String path) {
file = new FileInputStream(linkFile); try (FileInputStream file = new FileInputStream(path)) {
properties.load(file); properties.load(file);
file.close(); System.out.println("✅ Loaded properties from: " + path);
} catch (Exception e) { } catch (IOException e) {
System.err.println("❌ Không thể load file: " + path);
e.printStackTrace(); e.printStackTrace();
} }
} }
/**
* Lấy giá trị theo key
*/
public static String getValue(String key) { public static String getValue(String key) {
String keyval = null; if (properties.isEmpty()) {
try { System.err.println("⚠️ Properties chưa được load. Gọi setFile() hoặc setDefaultFile() trước.");
if (file == null) { return null;
properties = new Properties();
linkFile = PathToProject.getCurrentDir() + relPropertiesFilePathDefault;
file = new FileInputStream(linkFile);
properties.load(file);
file.close();
} }
// Lấy giá trị từ file đã Set return properties.getProperty(key);
keyval = properties.getProperty(key);
} catch (Exception e) {
System.out.println(e.getMessage());
}
return keyval;
} }
public static void setValue(String key, String keyValue) { /**
try { * Ghi giá trị mới vào key
if (file == null) { */
properties = new Properties(); public static void setValue(String key, String value) {
file = new FileInputStream(PathToProject.getCurrentDir() + relPropertiesFilePathDefault); if (linkFile == null) {
properties.load(file); System.err.println("⚠️ Chưa set file để ghi. Gọi setFile() hoặc setDefaultFile() trước.");
file.close(); return;
out = new FileOutputStream(PathToProject.getCurrentDir() + relPropertiesFilePathDefault);
} }
//Ghi vào cùng file Prop với file lấy ra
out = new FileOutputStream(linkFile); try (FileOutputStream out = new FileOutputStream(linkFile)) {
System.out.println(linkFile); properties.setProperty(key, value);
properties.setProperty(key, keyValue);
properties.store(out, null); properties.store(out, null);
out.close(); System.out.println("✅ Saved key=" + key + " to file: " + linkFile);
} catch (Exception e) { } catch (IOException e) {
System.out.println(e.getMessage()); System.err.println("❌ Không thể ghi vào file: " + linkFile);
e.printStackTrace();
} }
} }
} }
...@@ -10,9 +10,11 @@ import trinhQC.com.drivers.DriverManager; ...@@ -10,9 +10,11 @@ import trinhQC.com.drivers.DriverManager;
import java.awt.*; import java.awt.*;
import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.StringSelection;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.sql.Driver;
import java.time.Duration; import java.time.Duration;
import java.util.List; import java.util.List;
public class Key { public class Key {
private static int EXPLICIT_WAIT_TIMEOUT = 10; private static int EXPLICIT_WAIT_TIMEOUT = 10;
private static int WAIT_PAGE_LEADED_TIMEOUT = 30; private static int WAIT_PAGE_LEADED_TIMEOUT = 30;
...@@ -42,7 +44,8 @@ public class Key { ...@@ -42,7 +44,8 @@ public class Key {
} }
return getWebElement(by); return getWebElement(by);
} }
public static void clickElementWithJS(By by){
public static void clickElementWithJS(By by) {
JavascriptExecutor js = (JavascriptExecutor) DriverManager.getDriver(); JavascriptExecutor js = (JavascriptExecutor) DriverManager.getDriver();
waitForPageLoaded(); waitForPageLoaded();
waitForElementVisible(by); waitForElementVisible(by);
...@@ -83,6 +86,7 @@ public class Key { ...@@ -83,6 +86,7 @@ public class Key {
getWebElement(by).sendKeys(value); getWebElement(by).sendKeys(value);
logConsole("Set text " + value + " on element " + by); logConsole("Set text " + value + " on element " + by);
} }
public static void uploadFileRobotClass(String FileLocation) { public static void uploadFileRobotClass(String FileLocation) {
try { try {
robot = new Robot(); robot = new Robot();
...@@ -102,7 +106,6 @@ public class Key { ...@@ -102,7 +106,6 @@ public class Key {
} }
public static String getTextElement(By by) { public static String getTextElement(By by) {
waitForElementVisible(by); waitForElementVisible(by);
logConsole("Get text of element " + by); logConsole("Get text of element " + by);
...@@ -145,7 +148,7 @@ public class Key { ...@@ -145,7 +148,7 @@ public class Key {
} }
} }
public static void waitForElementVisible( By by, int second) { public static void waitForElementVisible(By by, int second) {
WebDriverWait wait = new WebDriverWait(DriverManager.getDriver(), Duration.ofSeconds(second), Duration.ofMillis(500)); WebDriverWait wait = new WebDriverWait(DriverManager.getDriver(), Duration.ofSeconds(second), Duration.ofMillis(500));
wait.until(ExpectedConditions.visibilityOfElementLocated(by)); wait.until(ExpectedConditions.visibilityOfElementLocated(by));
...@@ -156,7 +159,8 @@ public class Key { ...@@ -156,7 +159,8 @@ public class Key {
wait.until(ExpectedConditions.visibilityOfElementLocated(by)); wait.until(ExpectedConditions.visibilityOfElementLocated(by));
} }
public static List getWebElements(By by){
public static List getWebElements(By by) {
return DriverManager.getDriver().findElements(by); return DriverManager.getDriver().findElements(by);
} }
...@@ -177,6 +181,31 @@ public class Key { ...@@ -177,6 +181,31 @@ public class Key {
wait.until(ExpectedConditions.elementToBeClickable(by)); wait.until(ExpectedConditions.elementToBeClickable(by));
} }
public static void scrollHorizontallyInElement(By element, int pixels) {
WebElement el = DriverManager.getDriver().findElement(element);
JavascriptExecutor js = (JavascriptExecutor) DriverManager.getDriver();
js.executeScript("arguments[0].scrollLeft += arguments[1];", el, pixels);
}
// Chon checkbox trong dropdown
public static void chonNhanSu(String... nhanSus) {
// Click mở dropdown
WebElement dropdown = DriverManager.getDriver().findElement(
By.xpath("//label[normalize-space()='Nhân sự']/following::div[contains(@class,'form-control')]")
);
dropdown.click();
// Lặp và chọn từng nhân sự
for (String nhanSu : nhanSus) {
WebElement option = DriverManager.getDriver().findElement(
By.xpath("//div[contains(text(),'" + nhanSu + "')]")
);
option.click();
}
}
// public static void verifyElementText(By by, String textValue, String message){ // public static void verifyElementText(By by, String textValue, String message){
// waitForPageLoaded(); // waitForPageLoaded();
// waitForElementVisible(by); // waitForElementVisible(by);
...@@ -277,12 +306,63 @@ public class Key { ...@@ -277,12 +306,63 @@ public class Key {
} }
} }
} }
public static void selectDropdownByVisibleText(WebDriver driver, By locator, String visibleText) { public static void selectDropdownByVisibleText(WebDriver driver, By locator, String visibleText) {
WebElement dropdownElement = driver.findElement(locator); WebElement dropdownElement = driver.findElement(locator);
Select dropdown = new Select(dropdownElement); Select dropdown = new Select(dropdownElement);
dropdown.selectByVisibleText(visibleText); dropdown.selectByVisibleText(visibleText);
} }
// search 1 text
public static void verifyTextInTable(String expectText) {
// lất tất cả cell trong bảng
List<WebElement> allCells = DriverManager.getDriver().findElements(By.xpath("//table//tbody//td"));
Boolean isFound = false;
//Duyeejet qua tung cell
for (WebElement cell : allCells) {
if (cell.getText().trim().equalsIgnoreCase(expectText.trim())) {
isFound = true;
break;
}
}
//check result
Assert.assertTrue(isFound, "Khong tim thay" + expectText + "trong bang");
System.out.println("Da tim thay " + expectText + " trong bang");
}
// search nhieu text
public static void verifyMoreTextInTable(String... expectedValue) {
List<WebElement> allCells = DriverManager.getDriver().findElements(By.xpath("\"//table//tbody//td"));
for (String text : expectedValue) {
Boolean found = allCells.stream().anyMatch(cell -> cell.getText().trim().equalsIgnoreCase(text.trim()));
Assert.assertTrue(found, "khong tim thay" + text + "trong bang");
System.out.println("da tim thay" + text + "'");
}
}
public static boolean isElementDisplayed(By by) {
try {
waitForElementVisible(by, 5); // thêm wait để tránh lỗi
return getWebElement(by).isDisplayed();
} catch (Exception e) {
return false;
}
}
} }
url=https://fosco.erp.meu-solutions.com
username=admin
password=12345678
browser=chrome
timeout=10
exportCapturePath=test-output/screenshots
tygia=25000
package Fosco.com.commom; package Fosco.com.commom;
import io.github.bonigarcia.wdm.WebDriverManager; import io.github.bonigarcia.wdm.WebDriverManager;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*; import org.openqa.selenium.*;
...@@ -9,110 +10,103 @@ import org.openqa.selenium.edge.EdgeOptions; ...@@ -9,110 +10,103 @@ import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.ITestResult; import org.testng.ITestResult;
import org.testng.annotations.*; import org.testng.annotations.*;
import trinhQC.com.drivers.DriverManager; import trinhQC.com.drivers.DriverManager;
import trinhQC.com.reports.ExtentReportManager; import trinhQC.com.helpers.PropertiesHelper;
import trinhQC.com.reports.ExtentReportTestManager;
import java.awt.*;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.time.Duration;
public class BaseTest { public class BaseTest {
@BeforeMethod /* ================= BEFORE ================= */
@Parameters({"browser"})
public static void createDriver(@Optional("chrome") String browser) { @BeforeMethod(alwaysRun = true)
WebDriver driver = setupDriver(browser); public void setup() {
// ✅ Load properties MỘT LẦN – an toàn
PropertiesHelper.setDefaultFile();
// ✅ Lấy browser từ Data.properties
String browser = PropertiesHelper.getValue("browser");
if (browser == null || browser.isBlank()) {
browser = "chrome";
}
WebDriver driver = createDriver(browser);
// ✅ Set timeout
int timeout = Integer.parseInt(PropertiesHelper.getValue("timeout"));
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(timeout));
DriverManager.setDriver(driver); DriverManager.setDriver(driver);
// ❗ KHÔNG mở URL ở đây
} }
public static WebDriver setupDriver(String browserName) { /* ================= DRIVER ================= */
private WebDriver createDriver(String browser) {
WebDriver driver; WebDriver driver;
switch (browserName.trim().toLowerCase()) {
switch (browser.toLowerCase()) {
case "edge": case "edge":
driver = initEdgeDriver(); WebDriverManager.edgedriver().setup();
EdgeOptions edgeOptions = new EdgeOptions();
edgeOptions.setAcceptInsecureCerts(true);
driver = new EdgeDriver(edgeOptions);
break; break;
case "firefox": case "firefox":
driver = initFirefoxDriver(); WebDriverManager.firefoxdriver().setup();
driver = new FirefoxDriver();
break; break;
case "chrome": case "chrome":
default: default:
System.out.println("Browser: " + browserName + " → launching Chrome by default..."); WebDriverManager.chromedriver().setup();
driver = initChromeDriver(); ChromeOptions chromeOptions = new ChromeOptions(); //bỏ qa ssl
} chromeOptions.setAcceptInsecureCerts(true);
return driver; driver = new ChromeDriver(chromeOptions);
break;
} }
private static WebDriver initEdgeDriver() {
System.out.println("Launching Edge browser...");
WebDriverManager.edgedriver().setup();
EdgeOptions options = new EdgeOptions();
options.setAcceptInsecureCerts(true); // ✅ Bỏ qua lỗi HTTPS
WebDriver driver = new EdgeDriver(options);
driver.manage().window().maximize(); driver.manage().window().maximize();
return driver; return driver;
} }
private static WebDriver initChromeDriver() { /* ================= AFTER ================= */
System.out.println("Launching Chrome browser...");
WebDriverManager.chromedriver().setup();
ChromeOptions options = new ChromeOptions();
options.setAcceptInsecureCerts(true); // ✅ Bỏ qua lỗi HTTPS
WebDriver driver = new ChromeDriver(options);
driver.manage().window().maximize();
return driver;
}
private static WebDriver initFirefoxDriver() { @AfterMethod(alwaysRun = true)
System.out.println("Launching Firefox browser..."); public void takeScreenshotIfFail(ITestResult result) {
WebDriverManager.firefoxdriver().setup();
WebDriver driver = new FirefoxDriver();
driver.manage().window().maximize();
return driver;
}
@AfterMethod if (result.getStatus() != ITestResult.FAILURE) return;
public void takeScreenshotOnFailure(ITestResult result) {
// Chỉ thực hiện nếu test bị FAIL WebDriver driver = DriverManager.getDriver();
if (ITestResult.FAILURE == result.getStatus()) { if (driver == null) return;
WebDriver driver = DriverManager.getDriver(); // Lấy driver hiện tại
if (driver != null) {
try { try {
// Chụp ảnh màn hình String folder = PropertiesHelper.getValue("exportCapturePath");
TakesScreenshot ts = (TakesScreenshot) driver; if (folder == null || folder.isBlank()) {
File source = ts.getScreenshotAs(OutputType.FILE); folder = "test-output/screenshots";
// Tạo thư mục nếu chưa tồn tại
String screenshotDir = "./screenshots";
File dir = new File(screenshotDir);
if (!dir.exists()) {
dir.mkdirs(); // tạo thư mục nếu chưa có
} }
// Đặt tên file: tên của test case + .png File dir = new File(folder);
String screenshotName = result.getName() + ".png"; if (!dir.exists()) dir.mkdirs();
File destFile = new File(dir, screenshotName);
// Lưu file File src = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(source, destFile); File dest = new File(dir, result.getName() + ".png");
// In ra đường dẫn ảnh lưu FileUtils.copyFile(src, dest);
System.out.println("✅ Screenshot saved: " + destFile.getAbsolutePath()); System.out.println("📸 Screenshot saved: " + dest.getAbsolutePath());
} catch (IOException e) { } catch (Exception e) {
System.err.println("❌ Failed to save screenshot: " + e.getMessage()); System.err.println("❌ Screenshot failed: " + e.getMessage());
e.printStackTrace();
}
} else {
System.err.println("⚠️ WebDriver is null, cannot capture screenshot.");
} }
} }
}
@AfterMethod
public void closeDriver() {
@AfterMethod(alwaysRun = true)
public void tearDown() {
if (DriverManager.getDriver() != null) { if (DriverManager.getDriver() != null) {
DriverManager.quit(); DriverManager.quit();
} }
......
package Fosco.com.pages; package Fosco.com.pages;
import org.checkerframework.checker.units.qual.K;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.testng.Assert; import org.testng.Assert;
import trinhQC.com.helpers.PropertiesHelper;
import trinhQC.com.keywords.Key; import trinhQC.com.keywords.Key;
public class LoginPage { public class LoginPage {
private String URL = "https://fosco.erp.meu-solutions.com/vi/auth/sign-in";
By inputEmail = By.xpath("/html/body/div/div/div/div/div/div/div/form/div/div[2]/div[1]/input");
By inputPassword = By.xpath("/html/body/div/div/div/div/div/div/div/form/div/div[2]/div[2]/div/input");
By clickOnLoginButton = By.xpath("//button[contains(text(),'Đăng nhập')]");
// LOCATORS
private final By inputEmail = By.xpath("//input[@type='text' or @name='username']");
private final By inputPassword = By.xpath("//input[@type='password']");
private final By btnLogin = By.xpath("//button[.//text()[contains(.,'Đăng nhập')]]");
private final By toastLoginSuccess = By.xpath("//div[contains(text(),'Đăng nhập thành công')]");
public void LoginSuccess(String email, String password) { // OPEN LOGIN PAGE
Key.openURL(URL); public void openLoginPage() {
Key.setText(inputEmail, email); String url = PropertiesHelper.getValue("url");
Assert.assertNotNull(url, "❌ URL trong Data.properties bị null");
Key.openURL(url + "/vi/auth/sign-in");
}
// LOGIN ACTION
public void login(String username, String password) {
Assert.assertNotNull(username, "❌ Username null");
Assert.assertNotNull(password, "❌ Password null");
Key.setText(inputEmail, username);
Key.setText(inputPassword, password); Key.setText(inputPassword, password);
Key.clickElement(clickOnLoginButton); Key.clickElement(btnLogin);
Key.sleep(1.5);
} }
By messageSuccess = By.xpath("(//div[contains(text(),'Đăng nhập thành công')])[1]"); public void loginSuccess(String username, String password) {
openLoginPage();
login(username, password);
}
public void verifyLoginThanhCong(String messageloginthanhcong) { // VERIFY
boolean ketquamongmuon = Key.getTextElement(messageSuccess).trim().equals(messageloginthanhcong); public void verifyLoginSuccess() {
Assert.assertTrue(ketquamongmuon, "Fail"); boolean isDisplayed = Key.isElementDisplayed(toastLoginSuccess);
Assert.assertTrue(isDisplayed, "❌ Login không thành công");
} }
} }
package Fosco.com.pages;
import org.checkerframework.checker.units.qual.K;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import trinhQC.com.keywords.Key;
public class NgiepVuKhachhangPage {
// go to Nghiep vu page
By hoverOnNVitem = By.xpath("//button[contains(text(),'Nghiệp vụ')]");
By clickOnKHitem = By.xpath("//div[contains(text(),'Khách hàng')]");
By clickOnSearchBox =By.xpath("/html/body/div/div/div/div[2]/div[2]/div[2]/div[1]/form/div/input");
// go to Gom nhom nhan su page
By scrollToFooter = By.xpath("//div[contains(text(),'Điều khoản sử dụng')]");
By scrollHorizone = By.xpath("/html/body/div[1]/div/div/div[2]/div[2]/div[2]/div[2]/div[1]");
By clickOMenuitem = By.xpath("//tr[td[normalize-space()='CQA02']]//button[contains(@aria-haspopup, 'menu')]");
By clickOnGomNhomOption = By.xpath("//span[contains(text(),'Gom nhóm nhân sự')]");
// Tạo nhom
By clickOnTaoNhomButton = By.xpath("//span[contains(text(),'Tạo nhóm')]");
By inputTennhomBox = By.xpath("//input[@placeholder='Nhập thông tin']");
By clickOnMSTDropdown = By.xpath("//button[@id='_r_71_-form-item']");
By selectMstFirst = By.xpath("//div[@role='option'])[1]");
By clickOnBhxhDropdown = By.xpath("//label[normalize-space()='Mã BHXH']/following-sibling::div//button");
By selectOnBhxhFirst = By.xpath("//div[@role='option'])[1]");
By clickOnNhanSuDropdown = By.xpath("//label[normalize-space()='Nhân sự']/following-sibling::div//button");
By clickOnLuuButton = By.xpath("//button[text()='Lưu']");
// bang luong don vi
By clickOnDenBangLuongOption =
By.xpath("//span[contains(text(),'Đến bảng lương')]");
By clickOnTygia =
By.xpath("//button[@aria-describedby='radix-_r_9p_']");
By inputTygia =
By.xpath("//input[@id='_r_9q_.form-item']");
By clickOnApDungbtn =
By.xpath("//button[contains(text(),'Áp dụng')]");
// hàm tìm kiếm từ khóa
public void SearchForKeyword (String name){
Key.clickElement(hoverOnNVitem);
Key.clickElement(clickOnKHitem);
Key.setText(clickOnSearchBox,name);
Key.sleep(1.5);
Key.verifyTextInTable("CQA02");
}
// Đi tơi màn hinh gom nhom
public void setUpGomnhom(){
Key.clickElement(hoverOnNVitem);
Key.clickElement(clickOnKHitem);
Key.scrollToElement(scrollToFooter);
Key.setText(clickOnSearchBox,"CQA02");
Key.scrollHorizontallyInElement(scrollHorizone,200);
Key.clickElement(clickOMenuitem);
Key.clickElement(clickOnGomNhomOption);
}
// Đi tới màn hình Bảng lương đơn vị
public void setUpBangLuong(){
Key.clickElement(hoverOnNVitem);
Key.clickElement(clickOnKHitem);
Key.scrollToElement(scrollToFooter);
Key.setText(clickOnSearchBox,"CQA02");
Key.scrollHorizontallyInElement(scrollHorizone,200);
Key.clickElement(clickOMenuitem);
Key.clickElement(clickOnDenBangLuongOption);
}
// hàm tao nhóm
public void createGroup (){
setUpGomnhom();
Key.clickElement(clickOnTaoNhomButton);
Key.setText(inputTennhomBox,"nhóm test auto");
Key.clickElement(clickOnMSTDropdown);
Key.sleep(1.5);
Key.clickElement(selectMstFirst);
Key.clickElement(clickOnBhxhDropdown);
Key.clickElement(selectOnBhxhFirst);
Key.clickElement(clickOnNhanSuDropdown);
Key.chonNhanSu("250756 - clt", "250711 - cc2");
Key.clickElement(clickOnLuuButton);
}
// Verify Tạo nhóm thành công
public void verifyCrteategroupSuccess(){
}
// Ham ap dung ty giá đặc biệt
public void changeValue (String tygia){
setUpBangLuong();
Key.clickElement(clickOnTygia);
Key.setText(inputTygia,tygia);
Key.clickElement(clickOnApDungbtn);
}
//Verify change tỷ giá
public void verifyChangeValuesuccess(){
}
}
...@@ -7,6 +7,7 @@ import Fosco.com.listeners.TestListener; ...@@ -7,6 +7,7 @@ import Fosco.com.listeners.TestListener;
import Fosco.com.pages.LoginPage; import Fosco.com.pages.LoginPage;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import trinhQC.com.helpers.ExcelHelper; import trinhQC.com.helpers.ExcelHelper;
import trinhQC.com.helpers.PropertiesHelper;
@Listeners(Fosco.com.listeners.TestListener.class) @Listeners(Fosco.com.listeners.TestListener.class)
...@@ -19,10 +20,11 @@ public class LoginTest extends BaseTest { ...@@ -19,10 +20,11 @@ public class LoginTest extends BaseTest {
public void LoginPass(){ public void LoginPass(){
loginPage = new LoginPage(); loginPage = new LoginPage();
excelHelper = new ExcelHelper(); excelHelper = new ExcelHelper();
excelHelper.setExcelFile("src\\main\\resources\\login.xlsx","login"); loginPage.loginSuccess(
loginPage.LoginSuccess(excelHelper.getCellData(1,0), PropertiesHelper.getValue("username"),
excelHelper.getCellData(1,1)); PropertiesHelper.getValue("password")
loginPage.verifyLoginThanhCong(excelHelper.getCellData(1,2)); );
loginPage.verifyLoginSuccess();
} }
} }
package Fosco.com.testcases;
import Fosco.com.commom.BaseTest;
import Fosco.com.pages.LoginPage;
import Fosco.com.pages.NgiepVuKhachhangPage;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
import trinhQC.com.helpers.ExcelHelper;
import trinhQC.com.helpers.PropertiesHelper;
@Listeners(Fosco.com.listeners.TestListener.class)
public class NghiepvuKhachHangTest extends BaseTest {
LoginPage loginPage;
ExcelHelper excelHelper;
NgiepVuKhachhangPage nghiepVuKhachHang;
@BeforeMethod
public void setupPages() {
loginPage = new LoginPage();
excelHelper = new ExcelHelper();
nghiepVuKhachHang = new NgiepVuKhachhangPage();
excelHelper.setExcelFile("src\\main\\resources\\login.xlsx","login");
}
@Test (priority = 1)
public void checkSearchCustomer() {
excelHelper.setExcelFile("src/main/resources/login.xlsx", "login");
loginPage.loginSuccess(
excelHelper.getCellData(1, 0),
excelHelper.getCellData(1, 1)
);
nghiepVuKhachHang.SearchForKeyword("CQA02");
}
@Test(priority = 2)
public void createGroupPass(){
//1.login
// loginPage = new LoginPage();
// nghiepVuKhachHang = new NgiepVuKhachhangPage();
loginPage.loginSuccess(
PropertiesHelper.getValue("username"),
PropertiesHelper.getValue("password")
);
//2. Mo form tao nhom
nghiepVuKhachHang.createGroup();
// 3.Check verify
nghiepVuKhachHang.verifyCrteategroupSuccess();
}
@Test(priority = 3)
public void applyTyGiaSucess(){
loginPage.loginSuccess(
PropertiesHelper.getValue("username"),
PropertiesHelper.getValue("password")
);
nghiepVuKhachHang.changeValue(
PropertiesHelper.getValue("tygia")
);
nghiepVuKhachHang.verifyChangeValuesuccess();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment