Search code examples
pythondjangoselenium-webdriverxpath

Python:Selenium finding element by XPATH by Django If statement class


I am trying to test a simple notification page in Django using Selenium to test whether notifications are marked as read. To do this, I have a notifications model which includes a boolean field, defaults to False if the notification hasn't been read. I want to be able to show that some are read, and some aren't by using css.

I have the following html which works exactly as I want it to when running runserver; however, I can't get it to pass the tests.

{% for notification in notifications %}
    <div class="notification-card {% if notification.read == False %} unread {% else %} read {% endif %}">
        <h3>Badge Awarded</h3>
{% endfor %}

Then in my Selenium test file, I have the following line. If I hardcode the class in the html file, this test passes, but if I try to add Django for the class selector, the test fails.

unread_notifications = self.browser.find_element(By.XPATH, '//div[@class="notification-card unread"]/h3')
self.assertEqual(unread_notifications.text, 'Badge Awarded')

How do I find the desired element? I have already tried using '//div[contains(@class="unread")]/h3' to no avail. I don't want to hardcode the html because the next test is to find the read notifications.


Solution

  • It was not able to find the elements because the XPATH statement is the equality of the class. In your template there are whitespaces inside the conditions. So when it is rendered it will be something like this:

    <div class="notification-card unread "></div>
    

    So in your statement and the rendered template "notification-card unread " is not equal to "notification-card unread" because of the whitespaces.

    To solve this problem you can use CSS_SELECTOR instead of XPATH:

    unread_notifications = self.browser.find_element(By.CSS_SELECTOR, 'div.notification-card.unread > h3')