Возникла проблема при размещении элемента внутри iFrame - PullRequest
1 голос
/ 01 апреля 2019

Я пытаюсь нажать кнопку «Radio Button», которая находится внутри iFrame. Я пытался переключить iFrame, но столкнулся с проблемами.

Я попытался определить, в каком iFrame лежит мой Элемент, но с ошибкой Нет, такой Кадр.

Общий доступ к моему сценарию, с помощью которого можно перейти на страницу, где я столкнулся с проблемой, нажав любую кнопку-переключатель.

WebDriver driver;
JavascriptExecutor jse;

public static void main(String[] args) 
{

    Sap_Demo demoObj = new Sap_Demo();

    demoObj.invokeBrowser();
    demoObj.initializeSAPFiory();
    demoObj.forecastMD61();

}



public void invokeBrowser()
{
    System.setProperty("webdriver.chrome.driver", "U:\\Research Paper\\Selenium\\Drivers\\Chrome\\chromedriver_win32\\chromedriver.exe");
    driver = new ChromeDriver();

    driver.manage().deleteAllCookies();
    driver.manage().window().maximize();
    driver.manage().timeouts().implicitlyWait(40, TimeUnit.SECONDS);
    driver.manage().timeouts().pageLoadTimeout(40, TimeUnit.SECONDS);
}

public void initializeSAPFiory()
{

    try 
    {
        Thread.sleep(1200);
        driver.get("https://dijon.cob.csuchico.edu:8042/erp");
        driver.findElement(By.id("USERNAME_FIELD-inner")).sendKeys("H4");
        Thread.sleep(1200);

        driver.findElement(By.id("PASSWORD_FIELD-inner")).sendKeys("Onsjhjsa1087");
        Thread.sleep(1200);

        driver.findElement(By.id("CLIENT_FIELD-inner")).clear();
        Thread.sleep(1200);

        driver.findElement(By.id("CLIENT_FIELD-inner")).sendKeys("485");
        Thread.sleep(1200);

        driver.findElement(By.xpath("//span[@class='sapMBtnContent sapMLabelBold sapUiSraDisplayBeforeLogin']")).click();
    } 
    catch (InterruptedException e) 
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

public void forecastMD61()
{

    try {
        driver.findElement(By.id("erpsim-tcode-btn-img")).click();
        Thread.sleep(1200);

        driver.findElement(By.id("TCode-input-inner")).sendKeys("MD61");
        Thread.sleep(1200);

        driver.findElement(By.id("TCode-launchBtn-content")).click();
        Thread.sleep(1200);


        /*driver.switchTo().frame(driver.findElement(By.xpath("//span[@id='M0:46:::4:2-imgSymb']")));
        driver.findElement(By.xpath("//span[@id='M0:46:::4:2-imgSymb']")).sendKeys("ABC");*/


        //driver.manage().timeouts().implicitlyWait(40, TimeUnit.SECONDS);
        //Thread.sleep(1600);


        driver.switchTo().frame("ITSFRAME1");
        WebDriverWait wait = new WebDriverWait(driver, 10);
        wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt("ITSFRAME1"));

        //WebElement E1 = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("M0:46:::4:2-imgStd")));
        WebElement E1 = driver.findElement(By.xpath("//span[@id='M0:46:::4:2-imgSymb']"));
        E1.click();

        //driver.findElement(By.id("M0:46:::4:2-imgStd")).click();
        //driver.findElement(By.xpath("//span[@id='M0:46:::4:2-imgStd']")).click();
        //Thread.sleep(1200);
    } 
    catch (InterruptedException e) 
    {
        e.printStackTrace();
    }

}

}

Получение ошибки как:

Exception in thread "main" org.openqa.selenium.NoSuchFrameException: no such frame

Источник HTML:

для iframe:

<iframe id="ITSFRAME1" name="itsframe1_20190401041759.3908120" noresize="1" frameborder="0" framespacing="0" border="0" scrolling="no" onload="null" style="visibility: visible; z-index: 999; top: 0px; left: 0px;" src="javascript:(function(){document.open();document.domain='dijon.cob.csuchico.edu';self.frameElement.oWguHandlerItsMgrFrame.finalize(); })();"></iframe> 

Для радиокнопок:

enter code here <span id="M0:46:::4:2-imgStd" class="lsRBImgStd lsCBImgStdDef lsCBImgStdDefHv"><span id="M0:46:::4:2-imgSymb" class="lsRBImgSymb lsRBImgSel"></span></span> 

Ответы [ 2 ]

0 голосов
/ 01 апреля 2019

Вот мой ответ на предыдущий вопрос по этому вопросу . (Копировать / Вставить). Это работает 100% времени (при условии, что у вас есть JQuery на странице; если нет, мы можем сделать альтернативу):

Так что в конечном итоге это идеальный вариант использования расширения, которое я сделал. Вот самая важная часть этого:

        /// <summary>
        /// Selenium sometimes has trouble finding elements on the page. Give it some help by using JQuery to grab the full qualified xpath to that element.
        /// </summary>
        /// <param name="cssSelector"></param>
        /// <returns></returns>
        public static string GetFullyQualifiedXPathToElement(string cssSelector, bool isFullJQuery = false, bool noWarn = false)
        {

            if (cssSelector.Contains("$(") && !isFullJQuery) {

                isFullJQuery = true;

            }
            string finder_method = @"
                        function getPathTo(element) {
                            if(typeof element == 'undefined') return '';
                            if (element.tagName == 'HTML')
                                return '/HTML[1]';
                            if (element===document.body)
                                return '/HTML[1]/BODY[1]';

                            var ix= 0;
                            var siblings = element.parentNode.childNodes;
                            for (var i= 0; i< siblings.length; i++) {
                                var sibling= siblings[i];
                                if (sibling===element)
                                    return getPathTo(element.parentNode)+'/'+element.tagName+'['+(ix+1)+']';
                                if (sibling.nodeType===1 && sibling.tagName===element.tagName)
                                    ix++;
                            }
                        }
            ";
            if(isFullJQuery) {

                cssSelector = cssSelector.TrimEnd(';');

            }
            string executable = isFullJQuery ? string.Format("{0} return getPathTo({1}[0]);", finder_method, cssSelector) : string.Format("{0} return getPathTo($('{1}')[0]);", finder_method, cssSelector.Replace("'", "\""));
            string xpath = string.Empty;
            try {

                xpath = BaseTest.Driver.ExecuteJavaScript<string>(executable);

            } catch (Exception e) {

                if (!noWarn)  {

                    Check.Warn(string.Format("Exception occurred while building a dynamic Xpath. Css selector supplied to locate element is \"{0}\". Exception [{1}].", cssSelector, e.Message));

                }

            }
            if (!noWarn && string.IsNullOrEmpty(xpath)) {

                Check.Warn(string.Format("Supplied cssSelector did not point to an element. Selector is \"{0}\".", cssSelector));

            }
            return xpath;

        }

С помощью этой логики вы можете передать селектор Jquery в ваш браузер через javascript executor. У JQuery нет проблем с поиском элементов, вложенных в iframes. Попробуйте что-то вроде этого:

driver.FindElement(By.XPath(GetFullyQualifiedXPathToElement("#MyDeeplyNestedElement")).Click();

https://gist.github.com/tsibiski/04410e9646ee9ced9f3794266d6c5a82

Не стесняйтесь удалять из этого метода / класса все, что не относится к вашей ситуации.

Почему / Как это внезапно делает элемент доступным для селена ????

Возможно, вы заметили, что если вы скажете selenium найти html-элемент iframe, а затем явно выполните поиск в WebElement iframe, вы сможете найти под ним дочерние элементы. Однако, предварительно не найдя каждый дочерний iframe, Selenium, похоже, не заглядывает внутрь iframe, если вы явно не помогаете ему через DOM.

JQuery не имеет этого ограничения. Он видит каждый зарегистрированный элемент DOM просто отлично, и будет нормально захватывать его. Получив элемент в виде объекта JQuery, вы можете создать путь тегов, родитель за родителем, вплоть до DOM. Когда логика будет завершена, у вас будет полностью квалифицированный XPath от вершины DOM до вложенного дочернего элемента. Затем, когда этот явный XPath передается в Selenium, вы удерживаете его руку в кроличьей норе через один или несколько фреймов, пока не натолкнетесь на нужный объект.

0 голосов
/ 01 апреля 2019

Попробуйте это ... driver.SwitchTo().DefaultContent(); IWebElement iframe = driver.FindElement(By.Id("ITSFRAME1")); driver.SwitchTo().Frame(iframe);

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...