Kein Element mit Locator-Fehler gefunden, nachdem mit Winkelmesser zu iframe gewechselt wurde

Nov 19 2020

Ich habe versucht, eingebettetes PDF mit Winkelmesser-Selen von der Webseite herunterzuladen. Derzeit muss ich die Datei nicht mehr herunterladen, da immer der folgende Fehler angezeigt wird:

  • Fehlgeschlagen: Mit dem Locator wurde kein Element gefunden: By (CSS-Selektor, * [id = "download"])

Die Schaltfläche kann auch nach dem Umschalten auf Frame nicht gefunden werden.

Ich habe auch den in der Antwort hier angegebenen Ansatz ausprobiert, bei dem der Wert des src-Attributs extrahiert wird und direkt zur URL gewechselt wird, jedoch dasselbe Problem. Der Download-Button (Symbol) wurde nicht gefunden.

Wir haben genau die gleichen Anforderungen, bei denen wir nur auf das in das PDF eingebettete Download-Symbol klicken müssen, das sich zufällig in einem Iframe befindet. Beispielseite wie diese .

Hier ist mein Code-Snippet.

        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();

AKTUALISIEREN:

Es wurde versucht, den folgenden Code wie in einer der vorgeschlagenen Antworten vor und nach dem Wechseln des Frames einzufügen, aber es wird ein Fehler angezeigt.

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();

Error:

 - 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)

Download-Symbol als Referenz:

Antworten

3 Anton Nov 26 2020 at 19:51

Auf der von Ihnen bereitgestellten Beispielseite gibt es keine Schaltfläche "Herunterladen", da diese Schaltfläche Teil des Browsers und nicht der Seite ist. Sie können es mit keiner Art von Selektor finden.

Aber wir haben pdfdort als geladen iframe, damit wir unseren eigenen Download-Button erstellen können:

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

Kopieren Sie diesen Code, gehen Sie zu Ihrer Seite , fügen Sie ihn in die Konsole ein und führen Sie ihn aus. Dadurch wird die Datei heruntergeladen.

Dies ist nur ein Beispiel, aber vielleicht können Sie diese Idee an Ihre Bedürfnisse anpassen.

AKTUALISIEREN

Ok, ich werde versuchen zu erklären, was sich unter der Haube befindet. Hier ist die gleiche Seite in verschiedenen Browsern: Chrome, FF, Edge, IE.

Wie Sie sehen können, sind die "inneren Inhalte" der PDF-Seite unterschiedlich, da es sich nicht um eine Seitenralative handelt, sondern vom Browser und seinen Plugins gesteuert wird.

Das Drücken des Symbols / der Schaltfläche "Herunterladen" entspricht dem Drücken von etwas im Plugin. Es ist nicht möglich.

Tatsächlich enthält die Seite selbst nur ein PDF-Objekt, nicht die Steuerelemente.

Zum Beispiel können Sie im IE die Schaltfläche "Herunterladen" nicht finden. Es existiert einfach nicht, aber wir können darauf drücken ("im Browser", nicht "in Seite"), schauen Sie:

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

Ich denke, dass das Problem, das Sie haben, auf die Schattenwurzel zurückzuführen ist.

  1. Versuchen Sie, die by.deepCss(selector)Winkelmesser-Methode zu verwenden. Wenn dies nicht funktioniert, sehen Sie sich die Problemumgehung hier an .

  2. Sie können das src- Attribut des iframe abrufen und in einem neuen Fenster öffnen. Dann sendKeys Strg + S.

  3. Sie können versuchen, als JavaScript-Code in Winkelmesser auszuführen:

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

Ich erhalte dies, während ich das Element inspiziere und "Chrome-Pfad kopieren" aus Chrome DevTools auswähle.

Referenz:
So interagieren Sie mit den Elementen in # shadow-root (offen), während das Löschen von
Browserdaten des Chrome-Browsers mit cssSelector deepCss ein Element innerhalb der Schattenwurzel in Protractor Protractor nicht identifiziert
: Eingabeelement in einem Schatten-DOM (Polymer nicht auswählen) ) using 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

im Winkelmesser sein Anti-Muster, um Verkettung zu mischen und zusammen zu warten:

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

Dieser Code hat die Arbeit gemacht

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);

Wenn es nicht funktioniert, stimmt möglicherweise etwas mit Ihrer Konfiguration nicht. Daher müssen Sie Ihre Frage aktualisieren und deren Inhalt einfügen