Utilizzo di XPATH per cercare testo contenente & nbsp;


120

Uso XPather Browser per controllare le mie espressioni XPATH su una pagina HTML.

Il mio obiettivo finale è utilizzare queste espressioni in Selenium per testare le mie interfacce utente.

Ho un file HTML con un contenuto simile a questo:

<Tr>
  <Td> abc </ td>
  <Td> & nbsp; </ td>
</ Tr>

Voglio selezionare un nodo con un testo contenente la stringa " &nbsp;".

Con una stringa normale come "abc" non ci sono problemi. Uso un XPATH simile a //td[text()="abc"].

Quando provo con un XPATH come //td[text()="&nbsp;"]se non restituisse nulla. Esiste una regola speciale per i testi con " &"?


La tua attuale trasformazione XSL non restituisce nulla? O solo Xpather?
Zack The Human,

Risposte:


89

Sembra che OpenQA , i ragazzi dietro Selenium, abbiano già affrontato questo problema. Hanno definito alcune variabili per abbinare esplicitamente gli spazi bianchi. Nel mio caso, devo usare un XPATH simile a //td[text()="${nbsp}"].

Ho riprodotto qui il testo di OpenQA relativo a questo problema (trovato qui ):

L'HTML normalizza automaticamente gli spazi all'interno degli elementi, ignorando gli spazi iniziali / finali e convertendo gli spazi extra, le tabulazioni e le nuove righe in un unico spazio. Quando Selenium legge il testo fuori dalla pagina, tenta di duplicare questo comportamento, quindi puoi ignorare tutte le tabulazioni e le nuove righe nel tuo HTML e fare asserzioni basate su come appare il testo nel browser quando viene visualizzato. Lo facciamo sostituendo tutti gli spazi non visibili (incluso lo spazio unificatore " &nbsp;") con un unico spazio. Tutte le nuove righe visibili ( <br>, <p>e le <pre>nuove righe formattate) devono essere conservate.

Usiamo la stessa logica di normalizzazione sul testo delle tabelle dei casi di test HTML Selenese. Questo ha una serie di vantaggi. In primo luogo, non è necessario guardare il sorgente HTML della pagina per capire quali dovrebbero essere le proprie asserzioni; I &nbsp;simboli " " sono invisibili all'utente finale, quindi non dovresti preoccuparti di loro quando scrivi i test selenesi. (Non è necessario inserire " &nbsp;" marcatori nel test case per affermare il testo su un campo che contiene " &nbsp;".) Puoi anche inserire nuovi caratteri e spazi extra nei tuoi <td>tag selenesi ; poiché utilizziamo la stessa logica di normalizzazione sul caso di test che facciamo sul testo, possiamo garantire che le asserzioni e il testo estratto corrisponderanno esattamente.

Questo crea un po 'di problemi in quelle rare occasioni in cui vuoi / hai davvero bisogno di inserire spazi bianchi extra nel tuo test case. Ad esempio, potrebbe essere necessario digitare del testo in un campo come questo: " foo ". Ma se scrivi semplicemente <td>foo </td>nel tuo test case selenese, sostituiremo i tuoi spazi extra con un solo spazio.

Questo problema ha una soluzione semplice. Abbiamo definito una variabile in selenese ${space}, il cui valore è un singolo spazio. È possibile utilizzare ${space}per inserire uno spazio che non sarà tagliato automaticamente, in questo modo: <td>foo${space}${space}${space}</td>. Abbiamo anche incluso una variabile ${nbsp}, che puoi usare per inserire uno spazio unificatore.

Nota che gli XPath non normalizzano gli spazi bianchi come facciamo noi. Se avete bisogno di scrivere un XPath come //div[text()="hello world"], ma il codice HTML del collegamento è davvero " hello&nbsp;world", è necessario inserire un vero e proprio " &nbsp;" nel caso di test Selenese per farlo per abbinare, in questo modo: //div[text()="hello${nbsp}world"].


1
Il link OpenQA non viene più caricato con successo
kjosh

1
Voglio solo notare che $ {nbsp} non funziona per me negli strumenti di sviluppo Selenium o Chrome, né lo è \u00a0. Quello che ha funzionato per me è stato digitare uno spazio unificatore, su Mac Alt+Shift+Space. La ricerca Alt+0160sul Web dice su Windows.
Cynic

25

Ho scoperto di poter fare la corrispondenza quando inserisco uno spazio unificatore hardcoded (U + 00A0) digitando Alt + 0160 su Windows tra le due virgolette ...

//table[@id='TableID']//td[text()=' ']

ha funzionato per me con il carattere speciale.

Da quello che ho capito, lo standard XPath 1.0 non gestisce i caratteri Unicode di escape. Sembra che ci siano funzioni per questo in XPath 2.0 ma sembra che Firefox non lo supporti (o ho frainteso qualcosa). Quindi hai a che fare con la tabella codici locale. Brutto, lo so.

In realtà, sembra che lo standard si basi sul linguaggio di programmazione che utilizza XPath per fornire la corretta sequenza di escape Unicode ... Quindi, in qualche modo, ho fatto la cosa giusta.


Utilizzando Xpather 1.4.1 in Firefox 2, // td [text () = ''] non produce risultati.
Zack The Human

Scusate. Non funziona per me. Il mio obiettivo finale è usarlo in Selenium per i test delle mie interfacce Web. Il selenio stesso mantiene le espressioni di test in una struttura XML e la digitazione Alt Windows sembra essere persa nel modo in cui. Inoltre, il mio & # 160; restituisce come in XML.
Bergeroy

Zack, come ho scritto, devi sostituire lo spazio tra le due virgolette con il carattere prodotto da Alt + 0160 (sul tastierino numerico).
PhiLho

4
Devo lavorare con successo anche con PHP:$col = $xpath->query("//p[text()=\"\xC2\xA0\"]");
hakre

@Bergory Funziona utilizzando Goniometro con driver Selenium
Damian Green,

4

Prova a utilizzare l'entità decimale &#160;invece dell'entità denominata. Se ciò non funziona, dovresti essere in grado di utilizzare semplicemente il carattere Unicode per uno spazio unificatore invece &nbsp;dell'entità.

(Nota: non l'ho provato in XPather, ma l'ho provato in Oxygen.)


2

Tenere a mente che un processore XML conforme agli standard sarà sostituito tutti i riferimenti di entità diverse da quelle standard cinque di XML ( &amp;, &gt;, &lt;, &apos;, &quot;) con il carattere corrispondente nella codifica di destinazione per il momento espressioni XPath vengono valutate. Dato questo comportamento, i suggerimenti di PhiLho e jsulak sono la strada da percorrere se vuoi lavorare con gli strumenti XML. Quando si immette &#160;l'espressione XPath, questa dovrebbe essere convertita nella sequenza di byte corrispondente prima che venga applicata l'espressione XPath.


1
No, se provi / usi XPath in XPather (GUI) o in JavaScript (nessuna sostituzione automatica delle entità, poiché non siamo in XML). Buoni consigli in altri ambienti XML (XSTL?).
PhiLho

1

Non riesco a ottenere una corrispondenza utilizzando Xpather, ma quanto segue ha funzionato per me con file XML e XSL semplici nel Blocco note XML di Microsoft:

<xsl:value-of select="count(//td[text()='&nbsp;'])" />

Il valore restituito è 1, che è il valore corretto nel mio caso di test.

Tuttavia, ho dovuto dichiarare nbsp come entità all'interno del mio XML e XSL utilizzando quanto segue:

<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#160;"> ]>

Non sono sicuro che questo ti aiuti, ma sono stato in grado di trovare effettivamente nbsp usando un'espressione XPath.

Modifica: il mio esempio di codice contiene effettivamente i caratteri "& nbsp;" ma l'evidenziazione della sintassi JavaScript lo converte nel carattere spazio. Non fatevi ingannare!


Puoi modificare il codice di esempio come è stato fatto per l'esempio nella mia domanda. Sostituisci la tua entità nbsp con & amp; nbsp ;.
Bergeroy

1

Cerca &nbsp;o solo nbsp- l'hai provato?


Riconosco che dovrebbe funzionare ma non sono esattamente sicuro di quello che trovo. Ci deve essere un modo in XPATH per codificare un certo modo in modo che corrisponda a ciò che sto cercando.
Bergeroy

Forse dovrei guardare verso un'espressione regolare.
Bergeroy

1

Secondo l'HTML che hai fornito:

<tr>
  <td>abc</td>
  <td>&nbsp;</td>
</tr>

Per individuare il nodo con la stringa &nbsp;è possibile utilizzare uno dei seguenti soluzioni basate:

  • Utilizzando text():

    "//td[text()='\u00A0']"
  • Utilizzando contains():

    "//td[contains(., '\u00A0')]"

Tuttavia, idealmente potresti voler evitare il personaggio NO-BREAK SPACE e utilizzare una delle seguenti strategie di localizzazione :

  • Utilizzando il <tr>nodo padre e following-sibling:

    "//tr//following-sibling::td[2]"
  • Utilizzando starts-with():

    "//tr//td[last()]"
  • Utilizzando il <td>nodo precedente e il followingnode andfratello successivo`:

    "//td[text()='abc']//following::td[1]"

Riferimento

È possibile trovare una discussione dettagliata pertinente in:


TL; dr

Carattere Unicode "NO-BREAK SPACE" (U + 00A0)


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.