2012-08-14 91 views
14

Estoy intentando localizar un elemento con una identificación generada dinámicamente. La última parte de la cadena es constante ("ReportViewer_fixedTable"), así que puedo usar eso para ubicar el elemento. He tratado de utilizar expresiones regulares en XPath:Encontrar un elemento por identificación parcial con Selenium en C#

targetElement = driver.FindElement(
    By.XPath("//table[regx:match(@id, "ReportViewer_fixedTable")]")); 

y localizar por cssSelector:

targetElement = driver.FindElement(
    By.CssSelector("table[id$='ReportViewer_fixedTable']")); 

Ni las obras. Cualquier sugerencia sera apreciada.

Respuesta

34

Eso se debe a que el selector CSS necesita ser modificado eras casi allí ...

driver.FindElement(By.CssSelector("table[id*='ReportViewer_fixedTable']"))` 

De http://sauceio.com/index.php/2010/01/selenium-totw-css-selectors-in-selenium-demystified/:

css=a[id^='id_prefix_'] 

Un enlace con un id que comienza con el texto id_prefix_.

css=a[id$='_id_sufix'] 

Un enlace con un id que termina con el texto _id_sufix.

css=a[id*='id_pattern'] 

Un enlace con un id que contiene el texto id_pattern.

Usted estaba usando un sufijo que supongo que no era el identificador de texto de enlace parcial que se suponía que debía utilizar (a menos que viera su html, lo que significa que intente mostrar su html la próxima vez). *= es confiable en cualquier situación sin embargo.

+0

¿Cómo aplico esto para hacer una coincidencia parcial para los nombres de clase CSS? Estoy tratando de buscar elementos de etiquetas que tengan la clase 'etiqueta personalizada' o 'etiqueta personalizable contable'. 'By.CssSelector (" label [class $ = custom-label ")' no parece funcionar. Solo puedo usar By.ClassName dos veces y combinar los resultados, pero aún me gustaría saber cómo se puede lograr con CssSelector. – atlantis

2

trate de usar

targetElement = driver.FindElement(By.XPath("//table[contains(@id, "ReportViewer_fixedTable")]")); 

Nota esta comprobará si todos los elementos que tienen ID que contiene (y no sólo termina con 'ReportViewer_fixedTable'). Trataré de encontrar una opción de expresión regular que sea la respuesta más precisa a tu pregunta.

+0

y sí, una manera sucia sería .//table[substring(@id, string-length (@id) - 22) = 'ReportViewer_fixedTable'] –

+0

Gracias, eso fue lo que hizo. –

0

Esta solución funcionará independientemente de la versión XPath. Primero, crea un método en alguna parte de tu clase de ayuda COMMON.

public static string GetXpathStringForIdEndsWith(string endStringOfControlId) 
    { 
     return "//*[substring(@id, string-length(@id)- string-length(\"" + endStringOfControlId + "\") + 1)=\"" + endStringOfControlId + "\"]"; 
    } 

En mi caso, por debajo es el ID del mando en diferentes versión de mi producto ::

v1.0 :: ContentPlaceHolderDefault_MasterPlaceholder_HomeLoggedOut_7_hylHomeLoginCreateUser

v2.0 :: ContentPlaceHolderDefault_MasterPlaceholder_HomeLoggedOut_8_hylHomeLoginCreateUser

Entonces, puede llamar al método anterior para encontrar el control que tiene cadena final estática.

By.XPath(Common.GetXpathStringForIdEndsWith("<End String of the Control Id>")) 

para el control de identificación que he mencionado para v1 & v2, lo uso, como a continuación:

By.XPath(Common.GetXpathStringForIdEndsWith("hylHomeLoginCreateUser")) 

La lógica general es que, puede utilizar la expresión XPath abajo para encontrar un control que termina con una cadena particular:

//*[substring(@id, string-length(@id)- string-length("<EndString>") + 1)="<EndString>"] 
Cuestiones relacionadas