2011-09-23 13 views
16

Quindi, ero assolutamente sconcertato su come farlo in Selenium, e non riuscivo a trovare la risposta da nessuna parte, quindi sto condividendo la mia esperienza.selezionando un iframe con selenio di pitone

Stavo cercando di selezionare un iframe e di non avere fortuna (o comunque non ripetibile). Il codice HTML si presentava così:

<iframe id="upload_file_frame" width="100%" height="465px" frameborder="0" framemargin="0" name="upload_file_frame" src="/blah/import/"> 
<html> 
    <body> 
     <div class="import_devices"> 
      <div class="import_type"> 
       <a class="secondary_button" href="/blah/blah/?source=blah"> 
        <div class="import_choice_image"> 
         <img alt="blah" src="/public/images/blah/import/blah.png"> 
        </div> 
        <div class="import_choice_text">Blah Blah</div> 
       </a> 
      </div> 
     </div> 
    </body> 
</html> 

Il codice python (che utilizza la libreria selenio) stava cercando di trovare questo iframe utilizzare questo:

@timed(650) 
def test_pedometer(self): 
    sel = self.selenium 
    ... 
    time.sleep(10) 
    for i in range(5): 
     try: 
      if sel.select_frame("css=#upload_file_frame"): break 
     except: pass 
     time.sleep(10) 
    else: self.fail("Cannot find upload_file_frame, the iframe for the device upload image buttons") 

ripetuto fallisce con ogni combinazione di comandi selenio Potrei trovare Il successo occasionale non sarebbe riproducibile, quindi forse era una sorta di condizione di gara o qualcosa del genere? Non ho mai trovato il modo giusto per farlo nel selenio.

risposta

6

Ciò che alla fine ha funzionato per me era:

 sel.run_script("$('#upload_file_frame').contents().find('img[alt=\"Humana\"]').click();") 

In sostanza, non utilizzare il selenio per trovare il link nella iframe e fare clic su di esso; usa jQuery. Il selenio ha la capacità di eseguire una parte arbitraria di javascript in apparenza (questo è python-selenio, sto indovinando il comando selenio originale è runScript o qualcosa del genere), e una volta che posso usare jQuery posso fare qualcosa del genere: Selecting a form which is in an iframe using jQuery

+3

Faresti meglio a usare il getEval di Selenium comando (probabilmente "get_eval" nei collegamenti Python) invece del suo comando runScript. getEval non ritorna fino al completamento del codice JavaScript, mentre runScript semplice inserisce un elemento

1

Il comando selectFrame del selenio accetta tutti i localizzatori standard come css=, ma ha anche un set aggiuntivo di locatori che funzionano specificamente con gli elementi FRAME e IFRAME.

Come the doc dice:

selectFrame (localizzatore) selezionare una cornice all'interno della finestra corrente. (È possibile richiamare questo comando più volte per selezionare i frame nidificati.) Per selezionare il frame principale, utilizzare "relativo = parent" come un localizzatore; per selezionare il frame superiore, utilizzare "relativo = top". È inoltre possibile selezionare un frame dal relativo numero di indice a 0; seleziona il primo frame con "index = 0" o il terzo frame con "index = 2".

Si può anche usare un'espressione DOM per identificare il fotogramma che si desidera direttamente, in questo modo: dom=frames["main"].frames["subframe"]

Argomenti: locator - un localizzatore elemento di identificazione un frame o iframe

In generale, è Avrai maggiore fortuna nell'usare i localizzatori specializzati, soprattutto se stabilisci il contesto giusto per primo (ad esempio, select_frame("relative=top"); select_frame("id=upload_file_frame");).

+0

Sì, selectFrame non ha funzionato per me. Non significa che non funzionerà per nessuno, ma ho trovato che effettivamente selezionare il frame circa una volta in 5. – rossdavidh

2

Non è necessario utilizzare JavascriptExecutor. Tutto quello che dovevo fare era interruttore nel telaio e quindi passare di nuovo fuori, in questo modo:

// do stuff on main window 
switch_to_frame(frame_reference) 
// then do stuff in the frame 
driver.switch_to_default_content() 
// then do stuff on main window again 

Finché si sta attenti a questo, non si avrà mai un problema. L'unica volta che uso sempre un JavascriptExecutor è di ottenere il focus sulla finestra poiché penso che l'uso di Javascript sia più affidabile in quel caso.

28

Questo ha funzionato per me con Python (v.2.7), WebDriver & Selenio durante il test con iframe e cercando di inserire i dati all'interno di un iframe:

self.driver = webdriver.Firefox() 

## Give time for iframe to load ## 
time.sleep(3) 
## You have to switch to the iframe like so: ## 
driver.switch_to_frame(driver.find_element_by_tag_name("iframe")) 
## Insert text via xpath ## 
elem = driver.find_element_by_xpath("/html/body/p") 
elem.send_keys("Lorem Ipsum") 
## Switch back to the "default content" (that is, out of the iframes) ## 
driver.switch_to_default_content() 
+1

In qualche modo il WebDriver trova gli elementi nell'iframe durante la ricerca con xpath. Ho provato a trovare elementi tramite CSS, ID ma mi ha sempre dato un errore di elemento non esistente (errore di timeout in realtà perché ho usato il comando waitForElement). Non pensavo che la ricerca di elementi da parte di xpath avrebbe fatto la differenza, ma per fortuna ho provato quando ero a corto di idee. Molte grazie! – GOstrowsky

+5

'driver.switch_to_frame()' ora è deprecato, usa 'driver.switch_to.frame()' –

0

Ecco un tutorial di lavoro che vi aiutano a capire come gestire iframe su una pagina web utilizzando il selenio WebDriver con Python: https://www.youtube.com/watch?v=sfdWF4vBZ2o

Questo comando viene utilizzato per gestire iframe: driver.switch_to.frame (frame_id)

2

Se iframe è il nodo dinamica, è anche possibile attendere per iframe appeare nce esplicitamente e quindi passare ad esso utilizzando ExpectedConditions:

from selenium.webdriver.support import expected_conditions as EC 
from selenium.webdriver.support.ui import WebDriverWait as wait 

driver = webdriver.Chrome() 
driver.get(URL) 
wait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it("iframe_name_or_id")) 

Se iframe non ha @id o @name può essere trovato come WebElement comune utilizzando driver.find_element_by_xpath(), driver.find_element_by_tag_name(), ecc ..:

wait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(driver.find_element_by_xpath("//iframe[@class='iframe_class']"))) 

Per torna da iframe:

driver.switch_to.default_content() 
Problemi correlati