Вот предположим, что есть у нас такой XPath-локатор: ====>> Цитата : xpath=//td[text()='my simple string'] <<==== Всё вроде бы просто - ищет ячейку таблицы в которой есть текст: my simple string. Но что делать если текст, который надо найти содержит одинарные кавычки, вот такой: my 'apos' string? Не беда, можно обрамить его в двойные кавычки в XPath-локаторе вот так: ====>> Цитата : xpath=//td[text()="my 'apos' string"] <<==== Всё прекрасно работает. Аналогично если текст содержит двойные кавычки, то обрамляем в одинарные. Но что делать если текст содержит как одинарные так и двойные кавычки, например: my 'apos' and "quot" string? Первая мысль - от'escape'ить их обратным слешем, вот так: ====>> Цитата : xpath=//td[text()='my \'apos\' and "quot" string'] <<==== И тут мы обнаруживаем, что escape'инг в XPath не работает :( К сожалению это не только в Selenium'е так, так во всём XPath'е. Как быть? Можно использовать такое решение: ====>> Цитата : xpath=//td[text()=concat('my ',"'",'apos',"'",' and "quot" string')] <<==== Т.е. мы всегда используем одинарные кавычки для обрамления, кроме самих одинарных кавычек, которые обрамляем двойными, а потом "склеиваем" строку. Теперь всё прекрасно работает.
Можно написать такой вот escape-метод для подобных случаев (Java): ##### Код { ##### /** * Escapes the characters in a passed string to be suitable to pass to an XPath expression. * <p/> * Because there is no escape character in XPath string values, this method is not really escapes passed string, but * transforms it using a little trick with XPath concatenation function. * <p/> * Algorithm is: <ol><li>If string is <code>null</code>, then <code>null</code> is returns.</li><li>If string * doesn't contains "'" (apostrophe) character, then it returns as is, but quotes with "'" (apostrophe) character. * For example: <code>abcd</code> string will be returned as <code>'abcd'</code>.</li><li>If string contains "'" * (apostrophe) character, then it splits into string tokens and replaces with XPath <code>concat()</code> function. * For example: <code>ab'cd'ef</code> string will be returned as <code>concat('ab',"'",'cd',"'",'ef')</code></li><ol> * * @param string String to escape. * @return Escaped string. */ @Nullable public static String escapeXPath(@Nullable String string) { if (string == null) { return null; } else if (string.contains("'")) { StringBuilder sb = new StringBuilder(); sb.append("concat('");
for (int i = 0; i < string.length(); i++) { char ch = string.charAt(i); if ('\'' == ch) { sb.append("',\"").append(ch).append("\",'"); } else { sb.append(ch); } }
Selenium - Functional Testing -> storeAttribute
2009-04-14 15:25 joika
Проблема следующая: нужно записать в переменную значение атрибута, но при условии что в нужном теге второй аттрибут будет определенного значения. То есть у меня есть select и у него option[@value='1'], option[@value='2'] и т д. Мне нужно записать значение value только у того option, у которого ещё при этом будет аттрибут selected, то есть //select/option[@selected='' and @value='5']
AutomatedQA - Functional Testing -> Как-то криво передаётся ссылка на объект CreateObject("Scripting.
2009-04-14 15:50 nicksh
Пишу функцию, которая перебирает файлы в папке. В качестве параметра передаю ей ссылку на объект FSO (CreateObject("Scripting.FileSystemObject")). Чтобы сэкономить один параметр, решил передавать в функцию этот параметр неявно - через локальную переменную проекта с типом "Object". В этом случае что-то работает, а что-то нет: ##### Код { ##### Set FSO = Project.Variables.pFSO 'Работает Set Folder = FSO.GetFolder("C:\123") 'Работает Set Fils = Folder.Files 'Работает Set CountFil = Fils.Count 'Работает For Each Fil In Fils 'НЕ Работает - говорит, что Fils - не коллекция ... Next ##### Код } ##### А вот если FSO = CreateObject("Scripting.FileSystemObject") - напрямую - а не через локальную переменную проекта - то работает всё: ##### Код { ##### Set FSO = CreateObject("Scripting.FileSystemObject") Set Folder = FSO.GetFolder("C:\123") 'Работает Set Fils = Folder.Files 'Работает Set CountFil = Fils.Count 'Работает For Each Fil In Fils 'Работает ... Next ##### Код } #####