HTML is tree-structured and my specs mirror the HTML structure. I check the parent node for correctness and then verify the children. I had thought Capybara supported hierarchical specs using "within" but that doesn't seem to work for views. It could be cockpit error on my part but Google searches didn't show any better way.
So I spent a little time adding to the RSpec DSL. I wanted to have describe "scope into a subnode" of the current subject (the current subject being the equivalent of a DOM node). I named the DSL "with_subnode". With_subnode acts like describe with the ability to change the subject to a subnode.
The current subject is assumed to be a Capybara node. with_subnode takes in the name of a Capybara::Node method (op:) to apply to the current subject plus any arguments (args:)
One starts by constructing a root_node using let( :root_node) do ... end. This should be the string form as present in the rendered attribute.
The with_root_node method converts the root_node string into a Capybara::Node::Simple and makes it the subject of the do...end.
The example:
The code:
Unique symbols with an external associative array are used instead of let(). let() order evaluation along with inadvertent infinite recursion made that solution problematic.
The with_subnode clause is converted into two describe clauses. The inner describe clause is what the user placed in the do...end. The outer describe clause establishes the new subject.
An extra "it should_not be_nil" clause is added after the subject clause. This clause ensures the subject clause will be evaluated before the inner describe clause.