t.me/atinfo_chat Telegram группа по автоматизации тестирования

Как на странице сайта определить ссылку по фрагменту текста и без учёта регистра текста?

Теги: #<Tag:0x00007f748642f7a0> #<Tag:0x00007f748642f688> #<Tag:0x00007f748642f570>

Имеется код со следующим сценарием:

  1. Поиск ссылок на странице
  2. Если текст содержит “программа на C#”, то код нажимает на ссылку.
private void button4_Click(object sender, EventArgs e)
        {
            List<IWebElement> Element = Browser.FindElements( By.CssSelector("#tabnews_newsc a") ).ToList();
 
            for (int i = 0; i < Element.Count; i++ )
            {
                String s = Element[i].Text;                
 
                if (s.Contains("программа на C#")) // если текст СОДЕРЖИТ
                {
                    Element[i].Click(); // КЛИК по новости, которая СОДЕРЖИТ искомый текст
                    break;
                }
            }
        }

ВОПРОС
Как сделать, чтобы поиск осуществлялся без учёта регистра текста для поиска?
Т.е. если текст содержит “программа на C#”, то переход осуществляется, а если текст содержит “Программа на C#” (слово “Программа” с большой буквы “П” ), то перехода по ссылке не происходит.

Перед сравнением текста переведите его в верхний или нижний регистр а потом сравнивайте с текстом соответствующим:

s.ToLower().Contains("программа на c#")

На счёт правильности кода не уверен. Но по идее должно работать)

P.S.: вообще проще через #xpath наверное вытаскивать только нужные элементы и уже кликать по ним

//h3//a[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZАБВГДЕЁЖЗИКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯ', 'abcdefghijklmnopqrstuvwxyzабвгдеёжзиклмнопрстуфхцчшщьыъэюя'), 'программа на c#')]
2 Симпатий

При использовании предложенной вами строчки появляется ошибка.

ОШИБКА
‘string’ does not contain a definition for ‘contains’ and no extension method ‘contains’ accepting a first argument of type ‘string’ could be found (are you missing a using directive or an assembly reference?)

Скрин

ВОПРОС
Не могли бы вы подсказать как её исправить?

PS
Только осваиваю WebDriver Selenium заранее прошу извинить, если вопрос элементарный

Ошибку устранил.
Всё работает…

Вы бы не могли подсказать как сделать с помощью xpath на примере моего кода?

Пробовал вставить вашу строку, что-то не срабатывает.

//h3//a[contains(lower-case(.), "программа на c#")]

Не уверен на счет #xpath сделал его на основе вашего #css-selectors . Делаете поиск элементов по этому xpath. У вас будет в итоге список элементов которые только содержат такой текст, соответственно обходите этот список и кликаете по каждому элементу или что там у вас делает тест)

1 Симпатия

не могу нигде найти описание это части кода.
Что это такое?
В частности "lower-case(.)"

На java:

List<WebElement> elements = driver.findElements(By.cssSelector("#tabnews_newsc a"));
        for (WebElement ls : elements)
        {
            if (ls.getText().equalsIgnoreCase("программа на C#")) // если текст СОДЕРЖИТ
            {
                ls.click(); // КЛИК по новости, которая СОДЕРЖИТ искомый текст
            }
        }
1 Симпатия

By XPath:

List<WebElement> elements = driver.findElements(By.xpath("//a[contains(text(), 'программа на c#')]"));
1 Симпатия

Данный код будет выбирать текст, если слово "программа… " будет с большой буквы “П”, т.е. “Программа”?

PS
Всем спасибо за ответы

Да, будет собирать только ссылки, которые буквально содержат текст “программа на c#”
В принципе с помощью XPath можно задать любые критерии отбора.

1 Симпатия

Lower-case приводит текст к нижнему регистру. А точка это короткая запись text()

1 Симпатия

насколько хорошо xpath поддерживает кодировки ?

может проще сделать на с# - передать ignorecase несколькими способами оставить необходимые

 e = d.FindElements(By.CssSelector("#tabnews_newsc a"));
  String matcher = "(?i:" + "программа на c#" + ")";
 if (Regex.IsMatch(e.Text, matcher, RegexOptions.IgnoreCase)) {
 }
1 Симпатия

Так же добавлю, что lower-case это XPath 2.0 - который в данный момент не поддерживается браузерами.
А точка это не text(), а текущая нода относительно предиката…

2 Симпатий

Настолько хорошо, насколько их поддерживает веб-браузер.

В принципе, уже видно, что существует несколько путей решений задачи топикстартера. Лично мне вариант с прямым поиском по XPath видится самым производительным, так как сразу формируется массив из нужных элементов. В вашем же случае сперва сформируется массив из всех ссылок, а потом он еще должен перебираться, сравнивая каждый элемент с шаблоном регулярного выражения.

1 Симпатия

Ну в конкретном случае . будет равносильна использованию text(). В других случаях это будет текущая нода.
P.S.: вот страшный вариант для xpath 1.0:

//h3//a[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZАБВГДЕЁЖЗИКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯ', 'abcdefghijklmnopqrstuvwxyzабвгдеёжзиклмнопрстуфхцчшщьыъэюя'), 'программа на c#')]
1 Симпатия

Нет. Читайте спеку.

1 Симпатия

Я про то что оно работает.

1 Симпатия

А я про то, что вы утверждаете, что в данной конструкции

Что неверно:

https://jsfiddle.net/a5n2o3L9/

1 Симпатия

Ясен пень оно будет работать по разному ) Я не утверждал что . == text(), я имел в виду что в некоторых случаях замена text() на . будет давать тот же результат. Мне так удобнее было записать пример и все. Главное что он работает.

1 Симпатия

Ну если для вас все ясно, расскажите топик-стартеру, что же просиходит к конструкции вида contains(.,'some text'), и чем оно отличается от contains(text(),'some text').

1 Симпатия