免责声明:此代码是在 Katalon Studio 的 Groovy 中开发的...
我正面临一系列错误,这些错误看起来像是特征和继承的组合......
我有这个类,叫做
MemberLeadListPage
,它被定义为:
package com.signaturemd.pages.list
import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject
import java.time.LocalDateTime
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import com.kms.katalon.core.model.FailureHandling
import com.kms.katalon.core.testobject.TestObject
import com.kms.katalon.core.webui.common.WebUiCommonHelper
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
import com.signaturemd.utils.ActionHandler
import com.signaturemd.utils.GeneralWebUIUtils
public class MemberLeadListPage extends BasePersonListPage {
public final String linkXpath = "//span[@title = 'Member Lead Name']/a";
public MemberLeadListPage() {
super("https://crm.zoho.com/crm/org724168703/tab/Potentials/custom-view/4623170000000087545/canvas/4623170000000293236");
}
@Override
public void deleteAllCreatedAfter(LocalDateTime time) {
((this) as BaseSublistActor).doActionsToAllCreatedAfter(time, [
{ List<WebElement> newlyCreatedRecords ->
newlyCreatedRecords.each { WebElement rowElement ->
GeneralWebUIUtils.OpenLinkInNewTab(WebUI.convertWebElementToTestObject(rowElement.findElement(By.xpath(linkXpath))))
WebUI.waitForPageLoad(5);
WebUI.waitForElementPresent(findTestObject('Page_Member Lead/First Row/Member Lead Name') , 5)
final TestObject openStageItem = findTestObject("Page_Member Lead/Second Row/Open step item")
GeneralWebUIUtils.ScrollDropdownOptionIntoView(openStageItem)
WebUI.click(openStageItem)
GeneralWebUIUtils.WaitForElementTextMatches(findTestObject("Page_Member Lead/First Row/Stage label"),
"Open",
5)
WebUI.click(findTestObject("Page_Member Lead/First Row/Delete button"))
GeneralWebUIUtils.HandleConfirmableModal(findTestObject("Page_Member Lead/Delete Modal/Modal"),
findTestObject("Page_Member Lead/Delete Modal/Confirm Delete button"))
GeneralWebUIUtils.CloseLastTab()
}
}
]);
}
@Override
public TestObject getFirstResult() {
return findTestObject("Page_Member Lead List/Member Table/First Result link");
}
@Override
public TestObject getOrganizationFilterCheckbox() {
return findTestObject('Page_Member Lead List/Filter Sidebar/Filter By Fields Subsection/Organization Filter/Organization checkbox')
}
@Override
public TestObject getOrganizationFilterTextField() {
return findTestObject('Page_Member Lead List/Filter Sidebar/Filter By Fields Subsection/Organization Filter/Organization text field');
}
@Override
public String getTableRowListXpath() {
return "${this.getTableDataXpath()}//tr[@data-zcqa = 'detailView']"
}
@Override
public String getTableDataXpath() {
return "//table[@data-zcqa = 'listViewTable']";
}
@Override
public String getTableRowCheckboxXpath(int rowNum) {
return "(${this.getTableDataXpath()}//span[@data-zcqa = 'selectEntity'])[${rowNum}]"
}
@Override
public String getTimestampRelativeXpath() {
return "//span[contains(@data-component, '\"COLUMNNAME\":\"CREATEDTIME\"')]";
}
}
...和
BasePersonListPage
延伸BaseListPage
...
...和
BaseListPage
实现SublistDeleter
,后者定义为:
package com.signaturemd.pages.list
import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject
import java.time.LocalDateTime
import org.openqa.selenium.WebElement
import com.kms.katalon.core.testobject.TestObject
import com.kms.katalon.core.util.KeywordUtil
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
import com.signaturemd.utils.GeneralWebUIUtils
public trait SublistDeleter extends BaseSublistActor {
public void deleteAllCreatedAfter(LocalDateTime time) {
this.doActionsToAllCreatedAfter(time, [
this.onClickOnCheckboxes(),
this.onMassDelete(),
]);
}
public Closure<List<WebElement>> onMassDelete() {
return { List<WebElement> recordsToDelete ->
KeywordUtil.logInfo("Clicking the dropdown button and option to delete all selected records...");
WebUI.click(findTestObject("Shared repository/Zoho pages/CRM/List pages/Actions dropdown button"))
final TestObject deleteDropdownOption = findTestObject("Shared repository/Zoho pages/CRM/List pages/Actions dropdown/Delete dropdown option")
WebUI.waitForElementVisible(deleteDropdownOption, 2)
WebUI.click(deleteDropdownOption)
WebUI.waitForElementNotVisible(deleteDropdownOption, 2)
GeneralWebUIUtils.HandleConfirmableModal(findTestObject("Shared repository/Zoho pages/CRM/List pages/Modal/Modal"),
findTestObject("Shared repository/Zoho pages/CRM/List pages/Modal/Delete button"),
GeneralWebUIUtils.OnWaitForDisappear(WebUI.&waitForElementNotPresent, 4))
KeywordUtil.logInfo("All selected records successfully deleted!");
}
}
}
BaseSublistActor
定义为:
package com.signaturemd.pages.list
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.util.stream.Stream
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import com.kms.katalon.core.testobject.ConditionType
import com.kms.katalon.core.testobject.TestObject
import com.kms.katalon.core.util.KeywordUtil
import com.kms.katalon.core.webui.driver.DriverFactory
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
import com.signaturemd.utils.SMDDateUtils
public trait BaseSublistActor {
public static final DateTimeFormatter DateTimeFormat = DateTimeFormatter.ofPattern("MM-dd-yyyy h:mm a");
public void doActionsToAllCreatedAfter(LocalDateTime time, List<Closure<List<WebElement>>> onActionsList) {
KeywordUtil.logInfo("Fetching all records created after or at ${time.toString()}...")
final List<TestObject> allNewlyCreatedRecords = this.getAllCreatedAfter(time);
if (allNewlyCreatedRecords.isEmpty()) {
KeywordUtil.markWarning("There are no newly created records for this logged-in user...");
return;
}
onActionsList.each { Closure<List<WebElement>> onAction ->
onAction(allNewlyCreatedRecords);
};
}
public List<TestObject> getAllCreatedAfter(LocalDateTime time) {
final Stream<WebElement> foundWebElementsStream = DriverFactory.getWebDriver()
.findElements(By.xpath(this.getTableRowListXpath()))
.stream()
// Get the timezone offset of the user
LocalDateTime earliestCreationTime = foundWebElementsStream
.map { WebElement rowElement ->
return this.getCreatedTimeFromRowElement(rowElement)
}
.min { LocalDateTime firstTime, LocalDateTime secondTime ->
return firstTime.compareTo(secondTime);
}
.orElse(LocalDateTime.now())
final int timezoneDifference = SMDDateUtils.GetHoursDifference(time, earliestCreationTime);
return foundWebElementsStream
.filter { WebElement rowElement ->
final LocalDateTime createdTime = this.getCreatedTimeFromRowElement(rowElement);
final LocalDateTime adjustedTime = time.minusHours(timezoneDifference);
return createdTime.isAfter(adjustedTime) || createdTime.equals(adjustedTime);
}
.collect { WebElement rowElement -> return WebUI.convertWebElementToTestObject(rowElement) }
}
public String getTableRowListXpath() {
return "${this.getTableDataXpath()}//lyte-exptable-tr";
}
public String getTableDataXpath() {
return "//lyte-yield[@yield-name = 'contentYield']";
}
public LocalDateTime getCreatedTimeFromRowElement(WebElement rowElement) {
return LocalDateTime.parse(rowElement
.findElement(By.xpath(this.getTimestampRelativeXpath()))
.getText(),
this.DateTimeFormat);
}
public String getTimestampRelativeXpath() {
return "//*[contains(concat(' ', @class, ' '), ' newDTField ')]";
}
public Closure<List<WebElement>> onClickOnCheckboxes() {
return { List<WebElement> allNewlyCreatedRecords ->
allNewlyCreatedRecords
.eachWithIndex { TestObject tableRow, int idx ->
final int rowNum = idx + 1;
KeywordUtil.logInfo("Scrolling to and clicking checkbox to delete for row #${rowNum}...")
WebUI.scrollToElement(tableRow, 2);
WebUI.click(getTableRowCheckbox(rowNum));
}
}
}
public TestObject getTableRowCheckbox(int rowNum) {
return new TestObject("Shared repository/Zoho pages/CRM/List pages/Results Table/#${rowNum} table row checkbox")
.addProperty("xpath",
ConditionType.EQUALS,
this.getTableRowCheckboxXpath(rowNum),
)
}
public String getTableRowCheckboxXpath(int rowNum) {
return "(${this.getTableDataXpath()}//*[@lt-prop-class = 'customCheckBox'])[${rowNum}]";
}
}
IDE怎么会不识别派生类上来自基本特征
BaseSublistActor
的实现方法,甚至是SublistDeleter.onMassDelete()
的具体实现?