각도기를 사용하여 iframe으로 전환 한 후 로케이터 오류를 사용하여 요소를 찾을 수 없음

Nov 19 2020

나는 각도기 셀레늄을 사용하여 웹 페이지에서 임베디드 PDF를 다운로드하려고했습니다. 항상 다음과 같은 오류가 발생했기 때문에 현재 파일을 실제로 다운로드해야합니다.

  • 실패 : 로케이터를 사용하여 요소를 찾을 수 없음 : By (css selector, * [id = "download"])

프레임 전환 후에도 버튼을 찾을 수 없습니다.

또한 src 속성 값을 추출하고 URL로 직접 이동하지만 동일한 문제로 여기 에있는 답변에 표시된 접근 방식을 시도했습니다 . 다운로드 버튼 (아이콘)을 찾을 수 없습니다.

iframe 안에있는 PDF에 포함 된 다운로드 아이콘을 클릭하기 만하면되는 정확한 요구 사항이 있습니다. 같은 예제 페이지 이 .

다음은 내 코드 스 니펫입니다.

        const iframe = $('#printFrame'),             downloadBtn = $('#download'),
              content = $('#content');

        await this.disableWaitForAngular();
        await browser.wait(EC.visibilityOf(iframe),waitTimeout);
        console.log("Switching to iframe...");
        await browser.switchTo().frame(iframe.getWebElement());

        await browser.wait(EC.visibilityOf(content), waitTimeout);
        await browser.actions().mouseMove(content).perform();

        console.log("Waiting for download button.");
        await browser.wait(EC.visibilityOf(downloadBtn), waitTimeout);

        await downloadBtn.click();

        await browser.switchTo().defaultContent();
        await this.enableWaitForAngular();

최신 정보:

프레임 전환 전후에 제안 된 답변 중 하나에 제안 된대로 다음 코드를 삽입하려고 시도했지만 오류가 발생합니다.

const downloadIcon: WebElement = await browser.executeScript('return document.querySelector("#viewer").shadowRoot.querySelector("#toolbar").shadowRoot.querySelector("#downloads").shadowRoot.querySelector("#download").shadowRoot.querySelector("#icon > iron-icon");');

    await downloadIcon.click();

오류:

 - Failed: javascript error: Cannot read property 'shadowRoot' of null
(Session info: chrome=87.0.4280.66)
(Driver info: chromedriver=87.0.4280.20 (c99e81631faa0b2a448e658c0dbd8311fb04ddbd-refs/branch-heads/4280@{#355}),platform=Windows NT 10.0.14393 x86_64)

참고 용 다운로드 아이콘 :

답변

3 Anton Nov 26 2020 at 19:51

제공 한 예제 페이지 에는 "다운로드"단추가 없습니다.이 단추는 페이지가 아니라 브라우저의 일부이기 때문입니다. 어떤 유형의 선택기로도 찾을 수 없습니다.

하지만 pdf여기에로로드 iframe했으므로 자체 다운로드 버튼을 만들 수 있습니다.

a = document.createElement('a'); a.href = $('iframe').src; a.download = "hello.pdf"; a.click();

따라서이 코드를 복사하고 페이지 로 이동하여 콘솔에 붙여넣고 실행하십시오. 그러면 파일이 다운로드됩니다.

이것은 단지 예시 일 뿐이지 만 필요에 따라이 아이디어를 조정할 수 있습니다.

최신 정보

좋아, 나는 내부에 무엇이 있는지 설명하려고 노력할 것이다. 다음은 Chrome, FF, Edge, IE 와 같은 다른 브라우저 의 동일한 페이지 입니다.

보시다시피 PDF 페이지의 "내부 내용"은 페이지 랄러 티브가 아니기 때문에 브라우저와 플러그인에 의해 제어되기 때문에 다릅니다.

"다운로드"아이콘 / 버튼을 누르는 것은 플러그인 내부에서 무언가를 누르는 것과 같습니다. 불가능합니다.

실제로 페이지 자체에는 컨트롤이 아닌 PDF 개체 만 있습니다.

예를 들어 IE에서는 "다운로드"버튼을 찾을 수 없습니다. 그것은 단순히 존재하지 않지만 우리는 그것을 누를 수 있습니다 ( "페이지에서"가 아니라 "브라우저"에서),보세요 :

1 K.B. Nov 28 2020 at 17:30

나는 당신이 가지고있는 문제는 그림자 뿌리 때문이라고 생각합니다.

  1. by.deepCss(selector)각도기 방법을 사용해보십시오 . 이것이 작동하지 않으면 여기 에서 해결 방법을 확인 하십시오 .

  2. iframe 의 src 속성을 가져 와서 새 창에서 열 수 있습니다. 그런 다음 sendKeys Ctrl + S.

  3. 각도기에서 JavaScript 코드로 실행할 수 있습니다.

    document.querySelector("#viewer").shadowRoot.querySelector("#toolbar").shadowRoot.querySelector("#downloads").shadowRoot.querySelector("#download").shadowRoot.querySelector("#icon > iron-icon").click();

요소를 검사하고 Chrome DevTools에서 "Copy JS Path"를 선택하는 동안 이것을 얻었습니다.

참조 :
cssSelector
deepCss를 사용하여 Chrome 브라우저의 브라우징 데이터를 지우는 동안 # shadow-root (open) 내의 요소와 상호 작용하는 방법 deepCss가 Protractor Protractor 에서 Shadow Root 내부의 요소를 식별하지 못합니다
: 그림자 DOM 내부에서 입력 요소를 선택할 수 없음 (Polymer ) by.deepCss ( 'input') 사용
https://www.protractortest.org/#/api?view=ProtractorBy.prototype.deepCss
https://superuser.com/questions/505899/keyboard-shortcuts-for-chrome-pdf-viewer

PDHide Nov 19 2020 at 05:49

각도기에서 체인을 혼합하고 함께 대기하는 안티 패턴 :

isPDFDownloadSuccessful: () => Promise<boolean> = async() => {        
        await this.disableWaitForAngular(); //function equivalent to browser.waitForAngularEnabled(false);
        const iframe = await element(by.tagName("iframe"));
        console.log("Switching to iFrame...");        
        await browser.switchTo().frame(element(by.tagName('iframe')).getWebElement());
        await element(by.id("download")).click()
     
        //Insert here actions to check successful download 
        return true;    
    };
SergeyPleshakov Nov 23 2020 at 22:26

이 코드가 작동했습니다.

await browser.waitForAngularEnabled(false);
await browser.get('https://www.sebi.gov.in/enforcement/orders/jun-2019/adjudication-order-in-respect-of-three-entities-in-the-matter-of-prism-medico-and-pharmacy-ltd-_43323.html');
let $iFrame = $('iframe[src*="sebi"]'),
    $downloadButton = $('#download');
await browser.wait(ExpectedConditions.presenceOf($iFrame), 5000); await browser.switchTo().frame($iFrame.getWebElement());
await browser.wait(ExpectedConditions.presenceOf($downloadButton), 2000); await $downloadButton.click();
await browser.sleep(2500);
await browser.switchTo().defaultContent();
await browser.waitForAngularEnabled(true);

작동하지 않는 경우 구성에 문제가있을 수 있으므로 질문을 업데이트하고 내용을 포함해야합니다.