package com.paypal.ggrc.gdgrt.platform.automation.enums;
import java.util.HashMap;
import java.util.Map;
/**
* 不同的账号状态,存放在hashMap中,Key为颜色,Value为canvas中对应节点的css样式
* @author wwang13
*
*/
public class ColorizedAccountStatusUtil {
private ColorizedAccountStatusUtil(){}
private static Map<String,String> colorizedAccountStatusHashMap = new HashMap<String,String>();
static {
colorizedAccountStatusHashMap.put("Closed", "vertex-closed");
colorizedAccountStatusHashMap.put("Limited", "vertex-limited");
colorizedAccountStatusHashMap.put("Open", "vertex-open");
colorizedAccountStatusHashMap.put("Locked", "vertex-locked");
}
/**
* 给定一个待校验的样式和账号状态,看样式是否匹配
* @param cssStyle
* @param accountStatus
* @return
*/
public static Boolean verifyAccountStatusByStyle(String cssStyle, String accountStatus){
String matchedCssStyle = colorizedAccountStatusHashMap.get(accountStatus.trim());
return (cssStyle.contains(matchedCssStyle))?true:false;
}
}
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.paypal</groupId>
<artifactId>galaxi-automation</artifactId>
<packaging>jar</packaging>
<version>1.0.0-SNAPSHOT</version>
<name>galaxi-automation</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
<!-- maven 参数配置,这里引用不同的testng.xml -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<xmlFileName>testng.xml</xmlFileName>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- selenium -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>2.52.0</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-remote-driver</artifactId>
<version>3.4.0</version>
</dependency>
<!-- testng -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.9.9</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.13</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.java.dev.jna/jna -->
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.5.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.22</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>galaxi-automation</finalName>
<plugins>
<!-- 编译插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<!-- 添加插件 关联testNg.xml -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.17</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>testngconfig/${xmlFileName}</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>
</project>
package com.paypal.ggrc.gdgrt.platform.automation.scenario;
import org.testng.annotations.Test;
import org.testng.log4testng.Logger;
import com.paypal.ggrc.gdgrt.platform.automation.enums.ColorizedAccountStatusUtil;
import org.testng.annotations.Parameters;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.openqa.selenium.By;
import org.openqa.selenium.Point;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.*;
/**
* 自动化测试右边的canvas上的Edge
* @author wwang13
*
*/
public class CanvasEdgeOperationTest {
private static WebDriver driver;
private static final Logger LOGGER = Logger.getLogger(CanvasEdgeOperationTest.class);
@BeforeClass
public static void openBrowser() {
LOGGER.info("beforeClass: open the browser.");
System.setProperty("webdriver.chrome.driver","drivers/chromedriver.exe");
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.manage().deleteAllCookies();
// 与浏览器同步非常重要,必须等待浏览器加载完毕
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
}
@AfterClass
public void closeBrowser() {
LOGGER.info("afterClass: close the browser.");
driver.quit();
}
@Parameters({"baseUrl","correctSeedAccount"})
@Test
public void testCanvasNodeOperation(String baseUrl, String correctSeedAccount) throws Exception {
//打开URL
driver.get(baseUrl);
//定位到顶部搜索框
WebElement graphTopSearchBox = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[1]/div[1]/div/input"));
WebElement graphTopSearchClickIcon = driver.findElement(By.xpath("//*[@id='basic-addon']"));
//定位画布右上方的信息版
WebElement graphAccountNoInStatPanel = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[3]/font[1]"));
WebElement graphTransactionNoInStatPanel = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[3]/font[2]"));
WebElement graphAggreTransactionNoInStatPanel = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[3]/font[3]"));
WebElement graphLinkingsNoInStatPanel = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[3]/font[4]"));
///[Phase 1: 先在顶部的topSearchBox中输入一个有效的seedAccount]
//清空输入框
graphTopSearchBox.clear();
//输入框输入一个正确的seed account
graphTopSearchBox.sendKeys(correctSeedAccount);
Thread.sleep(1000);
//输入框点击发送
graphTopSearchClickIcon.click();
Thread.sleep(2000);
//verify 结果状态,信息板的统计数据都不再为空
assertNotNull(graphAccountNoInStatPanel.getText());
assertNotNull(graphTransactionNoInStatPanel.getText());
assertNotNull(graphAggreTransactionNoInStatPanel.getText());
assertNotNull(graphLinkingsNoInStatPanel.getText());
LOGGER.info("accountNoInStatPanel:"+graphAccountNoInStatPanel.getText());
LOGGER.info("transactionNoInStatPanel:"+graphTransactionNoInStatPanel.getText());
LOGGER.info("aggreTransactionNoInStatPanel:"+graphAggreTransactionNoInStatPanel.getText());
LOGGER.info("linkingsNoInStatPanel:"+graphLinkingsNoInStatPanel.getText());
//停留4秒方便看结果
Thread.sleep(4000);
///[Phase 2: 此时,右边canvas的图已经画完,现在开始针对canvas进行交互]
//Note: canvas的自动化操作编写方式比较特殊,体现在2个地方:
//a. 直接从Browser的Developer工具中获得的xPath不可以直接用于节点选择,针对svg和svg后面的路径部分,必须用name()函数来提取
//b. 不能直接触发交互,必须封装成Selenium Action的形式进行交互
//接下来大家可以接着往下写,这里只是举一个例子
//举一个Transaction的例子
//单个transaction,从浏览器获取到的xPath为: //*[@id="wrap"]/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[1]/div/svg/g[1]/g[1]/g[12]
//特别注意,这里需要2步:
//第一层通过xPath获得某个edge所在的container, container可以通过class 来识别出它是聚合边还是单边。
//第二层通过cssSelector,获得其真正的edge WebElement ,并分析得到对应的属性
//根据xPath找到对应的edge container
WebElement edgeContainerInCanvas = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[1]/div/*[name()='svg']/*[name()='g'][1]/*[name()='g'][1]/*[name()='g'][12]"));
String edgeContainerStyle = edgeContainerInCanvas.getAttribute("class");
LOGGER.info("edgeContainerStyle:"+edgeContainerStyle);
//通过识别出css style中是否包含"txn"文案,来判定交易是聚合Transaction还是常规Transaction
//常规Transaction的css style,其模式都是 eid_<txn>
//聚合Transaction的css style,其模式都是 eid_txnand<txn1>and<txn2>and<txnN>
LOGGER.info("TransactionType:"+(edgeContainerStyle.contains("txn")?"Aggregated Transaction":"Transaction"));
//获得edgeContainer之后,通过cssSelector 来获得其子元素,也就是真正的Edge对应的WebElement
//对于常规transaction ,其样式是 "edge edge-payment" ,对于HardLinking,其样式是"edge edge-hard linking",对于SoftLinking,其样式是"edge edge-soft linking"
WebElement edgeInCanvas = edgeContainerInCanvas.findElement(By.cssSelector("path.edge"));
LOGGER.info("edgeStyle:"+edgeInCanvas.getAttribute("class"));
//点击这条边
new Actions(driver).click(edgeInCanvas).build().perform();
Thread.sleep(4000);
//Transaction Properties的面板
WebElement infoPanel = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[1]/div/div/div[1]"));
//确认infoPanel被展现出来了
assertNotNull(infoPanel);
//获得InfoPanel上的文字,依然是通过cssSelector,通过选择"oside-title"的样式子元素,得到它的文案信息,比较其信息是否为"Transaction Properties"
//因为各种不同类型的edge,对应的属性面板上方的title都不一样
WebElement infoPanelText = infoPanel.findElement(By.cssSelector(".oaside-title"));
LOGGER.info("infoPanelText:"+infoPanelText.getText());
assertTrue("Transaction Properties".equals(infoPanelText.getText().trim()));
//获得对应的详情,并确保这些信息都不为空
String transactionTypeLiteral = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[1]/div/div/div[2]/div/div/div[2]/div/form/div[1]/div")).getText();
String timeCreatedLiteral = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[1]/div/div/div[2]/div/div/div[2]/div/form/div[2]/div")).getText();
String usdAmountLiteral = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[1]/div/div/div[2]/div/div/div[2]/div/form/div[3]/div")).getText();
String transactionStatusLiteral = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[1]/div/div/div[2]/div/div/div[2]/div/form/div[4]/div")).getText();
String transactionIdLiteral = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[1]/div/div/div[2]/div/div/div[2]/div/form/div[5]/div")).getText();
LOGGER.info("[ Transaction Properties ] transactionTypeLiteral: "+transactionTypeLiteral);
LOGGER.info("[ Transaction Properties ] timeCreatedLiteral: "+timeCreatedLiteral);
LOGGER.info("[ Transaction Properties ] usdAmountLiteral: "+usdAmountLiteral);
LOGGER.info("[ Transaction Properties ] transactionStatusLiteral: "+transactionStatusLiteral);
LOGGER.info("[ Transaction Properties ] transactionIdLiteral: "+transactionIdLiteral);
assertNotNull(transactionTypeLiteral);
assertNotNull(timeCreatedLiteral);
assertNotNull(usdAmountLiteral);
assertNotNull(transactionStatusLiteral);
assertNotNull(transactionIdLiteral);
//获得在有详情面板的情况下的Statistic Panel的位置信息(即包含 Account/Transaction/Aggregated Transaction/Linkings信息的bar条的位置信息)
WebElement statsPanelInDetailMode = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[3]"));
Point locationForStatsPanelInDetailMode = statsPanelInDetailMode.getLocation();
LOGGER.info("locationForStatsPanelInDetailMode:"+locationForStatsPanelInDetailMode);
//点击TransactionProperties上的"x"按钮来关闭此窗口
WebElement infoPanelCloseButton = infoPanel.findElement(By.cssSelector("button"));
infoPanelCloseButton.click();
//关闭之后校验Statistic Panel的位置最新信息
WebElement statsPanelInNonDetailMode = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[3]"));
Point locationForStatsPanelInNonDetailMode = statsPanelInNonDetailMode.getLocation();
LOGGER.info("locationForStatsPanelInNonDetailMode:"+locationForStatsPanelInNonDetailMode);
//通过比较横坐标,确认statistic Panel的位置右移了
assertTrue(locationForStatsPanelInNonDetailMode.getX() > locationForStatsPanelInDetailMode.getX());
assertTrue(locationForStatsPanelInNonDetailMode.getY() == locationForStatsPanelInDetailMode.getY());
Thread.sleep(4000);
}
}
package com.paypal.ggrc.gdgrt.platform.automation.scenario;
import org.testng.annotations.Test;
import org.testng.log4testng.Logger;
import com.paypal.ggrc.gdgrt.platform.automation.enums.ColorizedAccountStatusUtil;
import org.testng.annotations.Parameters;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.*;
/**
* 自动化测试右边的canvas上的Node
* 检查当在canvas上点击Node时,node在canvas中的相关属性是否和右边的信息Panel上的属性一致
* @author wwang13
*
*/
public class CanvasNodeOperationTest {
private static WebDriver driver;
private static final Logger LOGGER = Logger.getLogger(CanvasNodeOperationTest.class);
@BeforeClass
public static void openBrowser() {
LOGGER.info("beforeClass: open the browser.");
System.setProperty("webdriver.chrome.driver","drivers/chromedriver.exe");
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.manage().deleteAllCookies();
// 与浏览器同步非常重要,必须等待浏览器加载完毕
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
}
@AfterClass
public void closeBrowser() {
LOGGER.info("afterClass: close the browser.");
driver.quit();
}
@Parameters({"baseUrl","correctSeedAccount"})
@Test
public void testCanvasNodeOperation(String baseUrl, String correctSeedAccount) throws Exception {
//打开URL
driver.get(baseUrl);
//定位到顶部搜索框
WebElement graphTopSearchBox = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[1]/div[1]/div/input"));
WebElement graphTopSearchClickIcon = driver.findElement(By.xpath("//*[@id='basic-addon']"));
//定位画布右上方的信息版
WebElement graphAccountNoInStatPanel = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[3]/font[1]"));
WebElement graphTransactionNoInStatPanel = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[3]/font[2]"));
WebElement graphAggreTransactionNoInStatPanel = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[3]/font[3]"));
WebElement graphLinkingsNoInStatPanel = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[3]/font[4]"));
///[Phase 1: 先在顶部的topSearchBox中输入一个有效的seedAccount]
//清空输入框
graphTopSearchBox.clear();
//输入框输入一个正确的seed account
graphTopSearchBox.sendKeys(correctSeedAccount);
Thread.sleep(1000);
//输入框点击发送
graphTopSearchClickIcon.click();
Thread.sleep(2000);
//verify 结果状态,信息板的统计数据都不再为空
assertNotNull(graphAccountNoInStatPanel.getText());
assertNotNull(graphTransactionNoInStatPanel.getText());
assertNotNull(graphAggreTransactionNoInStatPanel.getText());
assertNotNull(graphLinkingsNoInStatPanel.getText());
LOGGER.info("accountNoInStatPanel:"+graphAccountNoInStatPanel.getText());
LOGGER.info("transactionNoInStatPanel:"+graphTransactionNoInStatPanel.getText());
LOGGER.info("aggreTransactionNoInStatPanel:"+graphAggreTransactionNoInStatPanel.getText());
LOGGER.info("linkingsNoInStatPanel:"+graphLinkingsNoInStatPanel.getText());
//停留4秒方便看结果
Thread.sleep(4000);
///[Phase 2: 此时,右边canvas的图已经画完,现在开始针对canvas进行交互]
//Note: canvas的自动化操作编写方式比较特殊,体现在2个地方:
//a. 直接从Browser的Developer工具中获得的xPath不可以直接用于节点选择,针对svg和svg后面的路径部分,必须用name()函数来提取
//b. 不能直接触发交互,必须封装成Selenium Action的形式进行交互
//特定交互的节点本身
WebElement nodeInCanvas = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[1]/div/*[name()='svg']/*[name()='g'][1]/*[name()='g'][2]/*[name()='g'][1]"));
//节点上的圆圈内的CountryCode标识
WebElement countryCodeForNodeInCanvas = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[1]/div/*[name()='svg']/*[name()='g'][1]/*[name()='g'][2]/*[name()='g'][1]/*[name()='text'][1]"));
//节点上的Full Name+Last Name 信息区
WebElement nameForNodeInCanvas = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[1]/div/*[name()='svg']/*[name()='g'][1]/*[name()='g'][2]/*[name()='g'][1]/*[name()='g']/*[name()='text'][1]"));
//获得节点的样式
String nodeCSSClass= nodeInCanvas.getAttribute("class");
//获得Node的相关属性
String nodeCountryCodeInfo = countryCodeForNodeInCanvas.getText();
String nodeNameInfo = nameForNodeInCanvas.getText();
LOGGER.info("[ Node Perspective ] countryCode: " + nodeCountryCodeInfo);
LOGGER.info("[ Node Perspective ] name: " + nodeNameInfo);
new Actions(driver).click(nodeInCanvas).build().perform();
Thread.sleep(2000);
//校验 AccountPropertiesPanel是否被展现出来了
WebElement accountPropertiesPanel = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[1]/div/div/div[1]"));
assertNotNull(accountPropertiesPanel);
//校验3个Tab 是否都被展现出来了
WebElement basicTab = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[1]/div/div/div[2]/div/div/div/div/ul/li[1]"));
WebElement activitiesTab = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[1]/div/div/div[2]/div/div/div/div/ul/li[2]"));
WebElement notesTab = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[1]/div/div/div[2]/div/div/div/div/ul/li[3]"));
assertNotNull(basicTab);
assertNotNull(activitiesTab);
assertNotNull(notesTab);
//获得Account Properties的"Basic"信息面板上的各个要素
String userNameLiteral = driver.findElement(By.xpath("//*[@id='view0']/div/div/form/div[1]/div")).getText();
String ppAccountLiteral = driver.findElement(By.xpath("//*[@id='view0']/div/div/form/div[2]/div")).getText();
String countryCodeLiteral = driver.findElement(By.xpath("//*[@id='view0']/div/div/form/div[3]/div")).getText();
String accountStatusLiteral = driver.findElement(By.xpath("//*[@id='view0']/div/div/form/div[4]/div")).getText();
String accountVerificationStatusLiteral = driver.findElement(By.xpath("//*[@id='view0']/div/div/form/div[5]/div")).getText();
String accountTypeLiteral = driver.findElement(By.xpath("//*[@id='view0']/div/div/form/div[6]/div")).getText();
String timeCreatedLiteral = driver.findElement(By.xpath("//*[@id='view0']/div/div/form/div[7]/div")).getText();
String last3MonthAvgGtpvLiteral = driver.findElement(By.xpath("//*[@id='view0']/div/div/form/div[8]/div")).getText();
String lastSentPaymentIdIn3YrsLiteral = driver.findElement(By.xpath("//*[@id='view0']/div/div/form/div[9]/div")).getText();
String lastSentPaymentStatusLiteral = driver.findElement(By.xpath("//*[@id='view0']/div/div/form/div[10]/div")).getText();
String lastSentPaymentDateLiteral = driver.findElement(By.xpath("//*[@id='view0']/div/div/form/div[11]/div")).getText();
String top5ReceivedCountLiteral = driver.findElement(By.xpath("//*[@id='view0']/div/div/form/div[12]/div")).getText();
String top5ReceivedAmountLiteral = driver.findElement(By.xpath("//*[@id='view0']/div/div/form/div[13]/div")).getText();
String top5SentCountLiteral = driver.findElement(By.xpath("//*[@id='view0']/div/div/form/div[14]/div")).getText();
String top5SentAmountLiteral = driver.findElement(By.xpath("//*[@id='view0']/div/div/form/div[15]/div")).getText();
LOGGER.info("[ Account Properties=>Basic ] userNameLiteral: "+userNameLiteral);
LOGGER.info("[ Account Properties=>Basic ] ppAccountLiteral: "+ppAccountLiteral);
LOGGER.info("[ Account Properties=>Basic ] countryCodeLiteral: "+countryCodeLiteral);
LOGGER.info("[ Account Properties=>Basic ] accountStatusLiteral: "+accountStatusLiteral);
LOGGER.info("[ Account Properties=>Basic ] accountVerificationStatusLiteral: "+accountVerificationStatusLiteral);
LOGGER.info("[ Account Properties=>Basic ] accountTypeLiteral: "+accountTypeLiteral);
LOGGER.info("[ Account Properties=>Basic ] timeCreatedLiteral: "+timeCreatedLiteral);
LOGGER.info("[ Account Properties=>Basic ] last3MonthAvgGtpvLiteral: "+last3MonthAvgGtpvLiteral);
LOGGER.info("[ Account Properties=>Basic ] lastSentPaymentIdIn3YrsLiteral: "+lastSentPaymentIdIn3YrsLiteral);
LOGGER.info("[ Account Properties=>Basic ] lastSentPaymentStatusLiteral: "+lastSentPaymentStatusLiteral);
LOGGER.info("[ Account Properties=>Basic ] lastSentPaymentDateLiteral: "+lastSentPaymentDateLiteral);
LOGGER.info("[ Account Properties=>Basic ] top5ReceivedCountLiteral: "+top5ReceivedCountLiteral);
LOGGER.info("[ Account Properties=>Basic ] top5ReceivedAmountLiteral: "+top5ReceivedAmountLiteral);
LOGGER.info("[ Account Properties=>Basic ] top5SentCountLiteral: "+top5SentCountLiteral);
LOGGER.info("[ Account Properties=>Basic ] top5SentAmountLiteral: "+top5SentAmountLiteral);
//校验搜索框中被搜索的目标account与右边Panel的 "Basic" Tab中的"PP Account"的内容是否一致
assertEquals(correctSeedAccount.trim(),ppAccountLiteral.trim());
//校验nodeInCanvas的文案的一致性-1 (canvas图上画的圆形节点的标识和右边Panel的"Basic" Tab中的"CountryCode"的内容是否一致
assertEquals(nodeCountryCodeInfo.trim(), countryCodeLiteral.trim());
//校验nodeInCanvas的文案的一致性-2 (canvas图上画的原型节点的下方名字信息和右边Panel的"Basic" Tab中的"Full Name(Last First)"的内容是否一致
assertEquals(nodeNameInfo.trim(),userNameLiteral.trim());
//校验nodeInCanvas的颜色样式(红|粉|绿|灰)是否与右边Panel的"Basic" Tab中的"Account Status"的内容一致
assertTrue(ColorizedAccountStatusUtil.verifyAccountStatusByStyle(nodeCSSClass, accountStatusLiteral.trim()));
//其他字段做简单的非空校验即可,也可以根据需要做一些细节的校验
assertNotNull(accountVerificationStatusLiteral);
assertNotNull(accountTypeLiteral);
assertNotNull(timeCreatedLiteral);
assertNotNull(last3MonthAvgGtpvLiteral);
assertNotNull(lastSentPaymentIdIn3YrsLiteral);
assertNotNull(lastSentPaymentStatusLiteral);
assertNotNull(lastSentPaymentDateLiteral);
assertNotNull(top5ReceivedCountLiteral);
assertNotNull(top5ReceivedAmountLiteral);
assertNotNull(top5SentCountLiteral);
assertNotNull(top5SentAmountLiteral);
//检查当点击了"Activities" Tab之后,对应的信息Panel是否能展示出来
activitiesTab.click();
Thread.sleep(1000);
WebElement activitiesInfoPanel = driver.findElement(By.xpath("//*[@id='activities0']"));
assertNotNull(activitiesInfoPanel);
Thread.sleep(1000);
//检查当点击了"Notes" Tab之后,对应的信息Panel是否能展现出来
notesTab.click();
Thread.sleep(1000);
WebElement notesInfoPanel = driver.findElement(By.xpath("//*[@id='notes0']"));
assertNotNull(notesInfoPanel);
Thread.sleep(1000);
//检查当点击了"Basic" Tab之后,对应的信息Panel是否能展现出来
basicTab.click();
Thread.sleep(1000);
WebElement basicInfoPanel = driver.findElement(By.xpath("//*[@id='view0']"));
assertNotNull(basicInfoPanel);
Thread.sleep(1000);
//方便查看结果
Thread.sleep(5000);
}
}
package com.paypal.ggrc.gdgrt.platform.automation.scenario;
import org.testng.annotations.Test;
import org.testng.log4testng.Logger;
import org.testng.annotations.Parameters;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.*;
/**
* 自动化测试左边的global filter
* @author wwang13
*
*/
public class GraphGlobalFilterTest {
private static WebDriver driver;
private static final Logger LOGGER = Logger.getLogger(GraphGlobalFilterTest.class);
@BeforeClass
public static void openBrowser() {
LOGGER.info("beforeClass: open the browser.");
System.setProperty("webdriver.chrome.driver","drivers/chromedriver.exe");
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.manage().deleteAllCookies();
// 与浏览器同步非常重要,必须等待浏览器加载完毕
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
}
@AfterClass
public void closeBrowser() {
LOGGER.info("afterClass: close the browser.");
driver.quit();
}
@Parameters({"baseUrl","correctSeedAccount"})
@Test
public void testGlobalFilter(String baseUrl, String correctSeedAccount) throws Exception {
//打开URL
driver.get(baseUrl);
//定位到顶部搜索框
WebElement graphTopSearchBox = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[1]/div[1]/div/input"));
WebElement graphTopSearchClickIcon = driver.findElement(By.xpath("//*[@id='basic-addon']"));
//定位左边的global filter
WebElement accountStatusDropDown = driver.findElement(By.xpath("//*[@id='collapseOne']/div/div/div/div[2]/div[2]/button/div"));
WebElement countryDropDown = driver.findElement(By.xpath("//*[@id='collapseOne']/div/div/div/div[3]/div[2]/button/div"));
WebElement transactionTypeDropDown = driver.findElement(By.xpath("//*[@id='collapseOne']/div/div/div/div[4]/div[2]/button/div"));
WebElement transactionStatusDropDown= driver.findElement(By.xpath("//*[@id='collapseOne']/div/div/div/div[5]/div[2]/button/div"));
WebElement paymentTypeDropDown = driver.findElement(By.xpath("//*[@id='collapseOne']/div/div/div/div[6]/div[2]/button/div"));
WebElement globalFilterOKButton = driver.findElement(By.xpath("//*[@id='collapseOne']/div/div/div/div[7]/button[1]"));
//定位画布右上方的信息版
WebElement graphAccountNoInStatPanel = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[3]/font[1]"));
WebElement graphTransactionNoInStatPanel = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[3]/font[2]"));
WebElement graphAggreTransactionNoInStatPanel = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[3]/font[3]"));
WebElement graphLinkingsNoInStatPanel = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[3]/font[4]"));
///[Phase 1: 先在顶部的topSearchBox中输入一个有效的seedAccount]
//清空输入框
graphTopSearchBox.clear();
//输入框输入一个正确的seed account
graphTopSearchBox.sendKeys(correctSeedAccount);
Thread.sleep(1000);
//输入框点击发送
graphTopSearchClickIcon.click();
Thread.sleep(2000);
///[Phase 2: 此时,右边canvas的图已经画完,现在开始左边的filter表单元素设置]
//Step 1: Global Filter表单中选择日期
JavascriptExecutor removeAttribute = (JavascriptExecutor)driver;
WebElement graphTimeRangeFrom = driver.findElement(By.xpath("//*[@id='startDatePicker']"));
WebElement graphTimeRangeTo = driver.findElement(By.xpath("//*[@id='endDatePicker']"));
//TODO, Need Research
//Step 2: Global Filter表单中从accountStatus下拉框中选择对应的值
accountStatusDropDown.click();
Thread.sleep(4000);
//选择accountStatus的第一个选项
WebElement accountStatusOption1 = driver.findElement(By.xpath("//*[@id='collapseOne']/div/div/div/div[2]/div[2]/div/div[2]/ul/li[1]/a"));
accountStatusOption1.click();
Thread.sleep(2000);
//再点一下dropdown把整个dropdown收回去
accountStatusDropDown.click();
Thread.sleep(1000);
//Step 3: Global Filter表单中从country下拉框中选择对应的值
countryDropDown.click();
Thread.sleep(4000);
//选择country的第一个选项
WebElement countryOption1 = driver.findElement(By.xpath("//*[@id='collapseOne']/div/div/div/div[3]/div[2]/div/div[3]/ul/li[2]/a"));
countryOption1.click();
Thread.sleep(2000);
//再点一下dropdown把整个dropdown收回去
countryDropDown.click();
Thread.sleep(1000);
//Step 4:Global Filter表单中从Transaction Type下拉框中选择对应的值
transactionTypeDropDown.click();
Thread.sleep(4000);
//选择Transaction Type的第一个选项
WebElement transactionTypeOption1 = driver.findElement(By.xpath("//*[@id='collapseOne']/div/div/div/div[4]/div[2]/div/div[2]/ul/li[1]/a"));
transactionTypeOption1.click();
Thread.sleep(2000);
//再点一下dropdown把整个dropdown收回去
transactionTypeDropDown.click();
Thread.sleep(1000);
//Step 5:Global Filter表单中从Transaction Status下拉框中选择对应的值
transactionStatusDropDown.click();
Thread.sleep(4000);
//选择Transaction Status的第一个选项
WebElement transactionStatusOption1 = driver.findElement(By.xpath("//*[@id='collapseOne']/div/div/div/div[5]/div[2]/div/div[2]/ul/li[1]/a"));
transactionStatusOption1.click();
Thread.sleep(2000);
//再点一下dropdown把整个dropdown收回去
transactionStatusDropDown.click();
Thread.sleep(1000);
//Step 6:Global Filter表单中从Payment Type下拉框中选择对应的值
paymentTypeDropDown.click();
Thread.sleep(4000);
//选择Payment Type的第一个选项
WebElement paymentTypeOption1 = driver.findElement(By.xpath("//*[@id='collapseOne']/div/div/div/div[6]/div[2]/div/div/ul/li[2]/a"));
paymentTypeOption1.click();
Thread.sleep(2000);
//Step 7: 提交global filter表单
globalFilterOKButton.click();
Thread.sleep(1000);
//verify 结果状态,信息板的统计数据都不再为空
assertNotNull(graphAccountNoInStatPanel.getText());
assertNotNull(graphTransactionNoInStatPanel.getText());
assertNotNull(graphAggreTransactionNoInStatPanel.getText());
assertNotNull(graphLinkingsNoInStatPanel.getText());
LOGGER.info("accountNoInStatPanel:"+graphAccountNoInStatPanel.getText());
LOGGER.info("transactionNoInStatPanel:"+graphTransactionNoInStatPanel.getText());
LOGGER.info("aggreTransactionNoInStatPanel:"+graphAggreTransactionNoInStatPanel.getText());
LOGGER.info("linkingsNoInStatPanel:"+graphLinkingsNoInStatPanel.getText());
//停留4秒方便看结果
Thread.sleep(4000);
}
}
package com.paypal.ggrc.gdgrt.platform.automation.scenario;
import org.testng.annotations.Test;
import org.testng.log4testng.Logger;
import org.testng.annotations.Parameters;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.*;
/**
* 自动化测试顶部的searchbox
* @author wwang13
*
*/
public class GraphTopSearchBoxTest {
private static WebDriver driver;
private static final Logger LOGGER = Logger.getLogger(GraphTopSearchBoxTest.class);
@BeforeClass
public static void openBrowser() {
LOGGER.info("beforeClass: open the browser.");
System.setProperty("webdriver.chrome.driver","drivers/chromedriver.exe");
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.manage().deleteAllCookies();
// 与浏览器同步非常重要,必须等待浏览器加载完毕
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
}
@AfterClass
public void closeBrowser() {
LOGGER.info("afterClass: close the browser.");
driver.quit();
}
@Parameters({"baseUrl","correctSeedAccount"})
@Test
public void testSingleSearchForTopSearchBox(String baseUrl, String correctSeedAccount) throws Exception {
//打开URL
driver.get(baseUrl);
//定位到顶部搜索框
WebElement graphTopSearchBox = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[1]/div[1]/div/input"));
WebElement graphTopSearchClickIcon = driver.findElement(By.xpath("//*[@id='basic-addon']"));
//定位画布右上方的信息版
WebElement graphAccountNoInStatPanel = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[3]/font[1]"));
WebElement graphTransactionNoInStatPanel = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[3]/font[2]"));
WebElement graphAggreTransactionNoInStatPanel = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[3]/font[3]"));
WebElement graphLinkingsNoInStatPanel = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[3]/font[4]"));
//清空输入框
graphTopSearchBox.clear();
//输入框输入一个正确的seed account
graphTopSearchBox.sendKeys(correctSeedAccount);
Thread.sleep(1000);
//输入框点击发送
graphTopSearchClickIcon.click();
Thread.sleep(1000);
//verify 结果状态,信息板的统计数据都不再为空
assertNotNull(graphAccountNoInStatPanel.getText());
assertNotNull(graphTransactionNoInStatPanel.getText());
assertNotNull(graphAggreTransactionNoInStatPanel.getText());
assertNotNull(graphLinkingsNoInStatPanel.getText());
LOGGER.info("accountNoInStatPanel:"+graphAccountNoInStatPanel.getText());
LOGGER.info("transactionNoInStatPanel:"+graphTransactionNoInStatPanel.getText());
LOGGER.info("aggreTransactionNoInStatPanel:"+graphAggreTransactionNoInStatPanel.getText());
LOGGER.info("linkingsNoInStatPanel:"+graphLinkingsNoInStatPanel.getText());
//停留4秒方便看结果
Thread.sleep(4000);
}
@Parameters({"baseUrl","correctSeedAccount1","correctSeedAccount2"})
@Test
public void testMultipleSearchForTopSearchBox(String baseUrl, String correctSeedAccount1, String correctSeedAccount2) throws Exception {
//打开URL
driver.get(baseUrl);
//定位到顶部搜索框
WebElement graphTopSearchBox = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[1]/div[1]/div/input"));
WebElement graphTopSearchClickIcon = driver.findElement(By.xpath("//*[@id='basic-addon']"));
//定位画布右上方的信息版
WebElement graphAccountNoInStatPanel = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[3]/font[1]"));
WebElement graphTransactionNoInStatPanel = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[3]/font[2]"));
WebElement graphAggreTransactionNoInStatPanel = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[3]/font[3]"));
WebElement graphLinkingsNoInStatPanel = driver.findElement(By.xpath("//*[@id='wrap']/div[4]/div[2]/div/div/div/div[1]/div[3]/div/div[2]/div[3]/font[4]"));
//输入框输入两个正确的seed account,中间用逗号分开
StringBuilder sb =new StringBuilder();
sb.append(correctSeedAccount1.trim()).append(",").append(correctSeedAccount2.trim());
//清空输入框
graphTopSearchBox.clear();
graphTopSearchBox.sendKeys(sb.toString());
Thread.sleep(1000);
//输入框点击发送
graphTopSearchClickIcon.click();
Thread.sleep(1000);
//verify 结果状态,信息板的统计数据都不再为空
assertNotNull(graphAccountNoInStatPanel.getText());
assertNotNull(graphTransactionNoInStatPanel.getText());
assertNotNull(graphAggreTransactionNoInStatPanel.getText());
assertNotNull(graphLinkingsNoInStatPanel.getText());
LOGGER.info("accountNoInStatPanel:"+graphAccountNoInStatPanel.getText());
LOGGER.info("transactionNoInStatPanel:"+graphTransactionNoInStatPanel.getText());
LOGGER.info("aggreTransactionNoInStatPanel:"+graphAggreTransactionNoInStatPanel.getText());
LOGGER.info("linkingsNoInStatPanel:"+graphLinkingsNoInStatPanel.getText());
//停留4秒方便看结果
Thread.sleep(4000);
}
}
网友评论