2015-04-15 2 views
1

Для приложения rails Я сейчас работаю над тем, что я недавно немного изменил дизайн, чтобы ссылка на вывеску больше не содержала якорный текст «Выйти», а вместо этого глификон из бутстрапа twitter. HTML-код для ссылки теперь выглядит следующим образом:Capybara не находит ссылку для ссылки по id

<a class="btn btn-primary btn-sm" data-method="delete" href="https://stackoverflow.com/users/sign_out" rel="nofollow"> 
    <span class="glyphicon glyphicon-log-out"></span> 
</a> 

тем временем мой водосвинка тест выглядит следующим образом:

context "when not logged in" do 

    it 'cannot create wikis' do 
    @free_user = create(:user) 
    login_as(@free_user, :scope => :user) 

    click_link "Sign out" 

    visit root_path 
    expect(page).to_not have_link('Create wiki') 
    end 
end 

Теперь, когда текст «Выйти» больше не существует, мне нужен новый способ идентифицировать ссылку. Проверяя документацию для capybara (или, скорее, this handy cheatsheet), похоже, я могу поставить либо текст ссылки, либо ее идентификатор. Так что я попытался дать ему идентификатор:

<a class="btn btn-primary btn-sm" data-method="delete" href="https://stackoverflow.com/users/sign_out" id="signout" rel="nofollow"> 
    <span class="glyphicon glyphicon-log-out"></span> 
</a> 

Так что теперь он получил идентификатор «SignOut» Однако, когда я делаю это изменение в тесте, он все равно не пройдет.

1) Standard (free) User when not logged in cannot create wikis 
    Failure/Error: click_link "signout" 
    Capybara::ElementNotFound: 
     Unable to find link "signout" 
    # ./spec/features/standard_user_role_spec.rb:107:in `block (3 levels) in <top (required)>' 

Я пытался убедиться, что я был еще вошедшего пользователя в тесте путем создания и ведения журнала в пользователя, как показано выше, и, добавив проверку, что HTML на странице содержит Здравствуйте, так как он говорит " Здравствуйте»и имя пользователя, когда пользователь вошел в систему:

expect(page).to have_content('Hello') 

Это дало мне еще одну ошибку, которую я не понимаю:

1) Standard (free) User when not logged in cannot create wikis 
    Failure/Error: expect(page).to have_content('Hello') 
    Capybara::ElementNotFound: 
     Unable to find xpath "/html" 
    # ./spec/features/standard_user_role_spec.rb:107:in `block (3 levels) in <top (required)>' 

Так что может быть здесь происходит?

Полная спецификация доступна here

ответ

1

Вы можете повторно добавить текст, но скрыть его от всех, кроме чтения с экрана:

<a class="btn btn-primary btn-sm" data-method="delete" href="https://stackoverflow.com/users/sign_out" id="signout" rel="nofollow"> 
    <span class="sr-only">Sign out</span> 
    <span class="glyphicon glyphicon-log-out"></span> 
</a> 

Это также повышает доступность несколько.

context "when not logged in" do 

    it 'cannot create wikis' do 
    @free_user = create(:user) 
    login_as(@free_user, :scope => :user) 

    visit root_path 
    click_link "Sign out", visible: false 

    expect(page).to_not have_link('Create wiki') 
    end 
end 

Обратите внимание, что мы явно сказать Capybara искать скрытый текст с опцией visible.

+0

Мне очень нравится этот ответ - это решает мою проблему и имеет преимущество улучшения доступности также. Ницца! Однако он все еще не отвечает на вопрос о том, почему capybara не находил идентификатор в первую очередь, о чем мне все еще интересно ... –

+0

Так что я, кажется, случайно переехал на сайт root_path после click_link - it ничего не нашел, потому что я еще не приземлился на странице ... –

+1

Да, я тоже это случалось со мной несколько раз. Мне нравится использовать ['save_and_open_page'] (https://coderwall.com/p/jsutlq/capybara-s-save_and_open_page-with-css-and-js), когда capybara не может найти то, что я ожидаю там. – max

-1

Для приложений, которые используют JS, это означает, что запрос отправляется с использованием, например, json, и запускается при нажатии на ссылку. (предположим, что разметка HTML такая же). Полезно следующий вызов:

find('Sign Out', visible: false).trigger('click') 

или id (если вы добавите его):

find(:css, "#sign-out", visible: false).trigger('click') 
+0

Это плохая общая рекомендация, так как не реплицирует то, что пользователь мог бы сделать –

+0

@TomWalpole и как бы вы исправили сообщение? –

+0

@TomWalpole в мае это единственный способ проверить, нажмите ссылку. –