在非抽象类中不能有抽象方法,尽管方法是在 traits 中实现的

问题描述 投票:0回答:0

免责声明:此代码是在 Katalon Studio 的 Groovy 中开发的...

我正面临一系列错误,这些错误看起来像是特征和继承的组合......

image|690x165

我有这个类,叫做

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()
的具体实现?

inheritance groovy interface traits
© www.soinside.com 2019 - 2024. All rights reserved.