The asserts I commonly use are: Assert that: - An element is present based on a CSS identifier, ideally ID - An element is present based on other selectors - When a user choose an option that should present a form, a form element is present - A form element is correctly not present (e.g. not redisplayed due to error) - The correct markup is present after an action is performed - An error form has the correct markup and information for validations - When I submit a form, application pages then list the new item as added - When I delete content as a user, the content no longer shows on the relevant pages You'll notice that all but the first two are 'take this action and then verify that the content is as expected'. Even the first two can be after an event. I think this is where you are struggling the most based on your description which basically described the elements present on initial page load. Testing adds much more value when you have a state, an action and then a resulting state that you test against. Avoid or be conservative in the following assertions because they are brittle, likely to break and require maintenance over time: - specific text for large blocks of text or text that is likely to have wording changed - specific text in one language when the site serves multiple languages - identifiers such as css class which may not be or remain unique - identifiers that are overly specific and include page layout I also use a Page Object approach for my element selectors so my tests look like this: context 'the driver correctly', :happy do scenario 'adds a violation', :js do visit_ready auto_policies_path(current_step: s4_path) add_valid_violation(child_seat_violation) wait_for_ajax expect(page).not_to have_css p.css_new_violation_form expect(find(p.css_added_violation)).to have_content child_seat_violation # ^^^ assertions end end