Ambitious Capybara
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Part Number | 50 | |
Number of Parts | 94 | |
Author | ||
License | CC Attribution - ShareAlike 3.0 Unported: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this | |
Identifiers | 10.5446/30638 (DOI) | |
Publisher | ||
Release Date | ||
Language |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
|
RailsConf 201550 / 94
1
4
7
8
9
10
11
13
14
16
17
19
21
24
25
29
30
33
34
35
36
37
39
40
42
47
48
49
50
51
53
54
55
58
59
61
62
64
65
66
67
68
70
71
77
79
81
82
85
86
88
92
94
00:00
FeedbackCompass (drafting)Projective planePoint (geometry)QuicksortRevision controlMultiplication signAreaCodeAnalytic continuationBitGroup actionComputer animation
01:20
Ruby on RailsStatistical hypothesis testingQuicksortUnit testingControl flowAnnihilator (ring theory)INTEGRALPersonal identification numberSoftware developerUniversal product codeCartesian coordinate systemMultiplication signStatistical hypothesis testingNumberMereologyProjective planeComplex (psychology)Software frameworkConfidence intervalGame theoryComputer filePoint (geometry)DemosceneMathematicsExecution unitProcedural programmingExtreme programmingDistortion (mathematics)RhombusComputer animation
03:04
AreaMathematicsElement (mathematics)Tube (container)Revision controlQuicksortComputer fileRaw image formatSinc functionInternetworkingPattern languageDefault (computer science)Statistical hypothesis testingSocial classFree variables and bound variablesWeb browserStatistical hypothesis testingBootingoutputPasswordCodeWeb pageProjective planeFlow separationEmailView (database)Software developerConfidence intervalComputer fontCartesian coordinate systemMereologyHookingForm (programming)INTEGRALWeb 2.0BitSemantics (computer science)Template (C++)Traverse (surveying)CurveProper mapServer (computing)Product (business)Chemical equationMarkup languageOverhead (computing)Software maintenanceInternet forumComplex (psychology)SoftwareCore dumpPerspective (visual)CounterexampleFeedbackCodecPersonal digital assistantTouchscreenCASE <Informatik>Software frameworkNumberEndliche ModelltheorieCellular automatonProcess (computing)Set (mathematics)Operator (mathematics)Device driverWater vaporGame controllerSurvival analysisChainLoginArithmetic meanSign (mathematics)Ideal (ethics)Right angleComputer animation
10:22
Element (mathematics)Statistical hypothesis testingStatistical hypothesis testingComputer configurationWeb browserField (computer science)Web pageWordWrapper (data mining)Attribute grammarEndliche ModelltheorieResultantCartesian coordinate systemQuicksortExterior algebraoutputEntire functionMarkup languageDescriptive statisticsForm (programming)Query languageTouchscreenMereologySocial classSoftware developerContent (media)Category of beingTerm (mathematics)Overhead (computing)Functional (mathematics)HookingMessage passingFitness functionComputer programmingOrder (biology)Uniform resource locatorMeta elementBitElectronic mailing listSinc functionRaw image formatPoint (geometry)Device driverData storage deviceHacker (term)Control flowEstimatorServer (computing)Complex (psychology)MathematicsVector spaceState of matterIntegrated development environmentWind tunnelWebsiteArmGenderClassical physicsRule of inferenceMixed realityCore dumpDeclarative programmingProcess (computing)AdditionGroup actionEqualiser (mathematics)Computer animation
17:41
Term (mathematics)1 (number)System callEndliche ModelltheorieNumberMultiplication signoutputObject (grammar)Web pageBlock (periodic table)MereologyStructural loadElement (mathematics)QuicksortDefault (computer science)Electronic signatureBitBackupField (computer science)Type theoryCASE <Informatik>Cartesian coordinate systemEmailOnline helpTable (information)Functional (mathematics)Matching (graph theory)Form (programming)Latent heatMoment (mathematics)HoaxReading (process)Interface (computing)Order (biology)Parity (mathematics)Right angleComputer configurationCategory of beingWrapper (data mining)Integrated development environmentQuery languageAreaUniform resource locatorDistanceSelectivity (electronic)File formatStatistical hypothesis testingComputer-assisted translationPrimitive (album)Statistical hypothesis testingLevel (video gaming)Different (Kate Ryan album)Spherical capEntire functionSocial classData storage deviceDevice driverModule (mathematics)Interactive televisionMarkup languageAttribute grammarHookingBoolean algebraCellular automatonInstance (computer science)ParsingState of matterInheritance (object-oriented programming)TimestampComputer animation
24:59
QuicksortStatistical hypothesis testingBitCartesian coordinate systemAddress spaceSet (mathematics)WindowLevel (video gaming)Sign (mathematics)Form (programming)Computer configurationService-oriented architectureRepository (publishing)Multiplication signoutputTheory of relativitySystem callStatistical hypothesis testingMereologySoftware bugGreatest elementService (economics)Web pageCASE <Informatik>Scripting languageMobile appCanadian Mathematical SocietyFlow separationCodeFunctional (mathematics)Decision theoryEinbettung <Mathematik>Element (mathematics)Virtual machineProper mapProcess (computing)Data storage deviceProduct (business)INTEGRALSystem administratorSingle-precision floating-point formatTable (information)TheoryEncryptionState of matterLine (geometry)NumberData managementClosed setEndliche ModelltheorieRow (database)DatabaseInsertion lossImplementationContent management systemAffine spaceGroup actionLoginServer (computing)Pattern languageObject (grammar)Feature spaceUnit testingInstance (computer science)Validity (statistics)Overhead (computing)Open setModal logicInteractive televisionElectronic mailing listWebsiteMultiplicationFeedbackClient (computing)Projective planeComputer animation
Transcript: English(auto-generated)
00:12
Hello, everyone. My name is Eduardo Gutierrez. I'm going to be talking to you today about ambitious capybara
00:20
This talk is brought to you by some very special people I've been unemployed for most of the time when I was working on this talk for the past few months So I don't have any actual companies that I'm sponsored by instead. I'm brought to you by These restaurants in the Boston area that would let me sit in their restaurant for like six hours a day coding Because it was getting a little bit old sitting at home kind of like even with all the snow I had to get out at some point
00:47
Additionally, I'd like to give a huge. Thanks and shout out to the Boston RB Ruby group I gave them a fruit like sort of early version of this talk. They gave me a lot of really great feedback And they've also just been they've also been a really great community for encouraging people to talk
01:02
Encouraging people to like get their voices out there, so I wouldn't be I wouldn't be here today presenting if it wasn't for them So now I have a very deep Confession that I want to tell you all it's it feels awkward just based on like sort of a lot of the projects I've worked on in various Ruby and rails projects, but I'm in love with capybara
01:23
and Maybe this doesn't seem weird to you But the number of times I've seen developers go into like a feature file and kind of just like slump over dislikes Just like what's going on here? What is this like this is test code? I'm not even like old production code And just the number of times I've encountered developers who just have
01:43
Very little faith in sort of integration tests due to like you know some bad experience or some complexity that they experienced in the past I've worked on a lot of projects for like integration test quality sort of slid in favor of sort of More unit tests or just sort of dealing with the burden of tests that would fail every now and then or test the
02:04
You know you don't have a lot of confidence in so you have this very big app And you're just sort of always like pins and needles is this feature gonna break something else in the application and so my goal today is to sort of dispel that for anyone here in the audience or to give you the Sort of tips and tricks that take back to your co-workers your friends to sort of
02:23
re-establish that confidence because when capybara first came out it sort of changed the game and what the kind of ambitious applications we could build with Ruby on Rails And in general any sort of Ruby based framework or not at this at this point and so the ability to
02:40
Test JavaScript to make assertions without having to couple or test the specific parts of the DOM and how it's laid out I think has gotten it has been a significant significant contributor to where we are today and sort of the kind of Applications we see out there that are built by rails and sort of inspires to build and create bigger and better things So I'd like to start out with some little-known facts about capybaras
03:05
Capybara or the hydrocorus hydrocarous originated from South America And doing research for this talk. I discovered the pronunciation of the name is under heavy debate I've heard some people pronounce it as capybara versus capybara
03:21
It's still up for debate. I've lost some friends over this Some very advanced facts about capybaras is they're semi-aquatic And I think that makes sense because capybara is like kind of like the giant biggest web rat so it has to Traverse the internet tubes underwater They can roam over areas spanning 25 acres
03:40
To me that means that they're capable of handling very large applications and they're very friendly animals a lot of people have them as pets so It's a very approachable framework or not framework tool So if you've had a bad experience, I hope to encourage you to check it out again
04:00
So I like to talk about a balancing it that I encounter a lot between Readability maintainability and performance and I find that this is sort of the core of what it is to like build a software project to Balance sort of how readable the project is you know how easy can anyone else get into it and understand what's going on? How maintainable is it you know can someone come in and easily make?
04:21
Make changes without compromising the rest of the application and then does it all perform very well Some might sit sort of I've heard feedback that readability and maintainability are kind of the same thing But examples I like counterexamples after that or you can have a very readable DSL like the rails router it makes a lot of sense, but if you go and look under the hood of like
04:43
complexity required for Maintaining that nice DSL sort of it's very you know there's a lot of overhead to that and then on the other Side of things you can have very maintainable well structured well composed code But it's still very difficult to like get into even though. It's well structured. There's still a high learning curve
05:04
And so then our idealist is you know be right in the center and when it comes to integration tests I tend to aim for just below the center as my sweet spot for like I'll worry about performance later I'm more interested in sort of my test serving as documentation that either a stakeholder could someday use or a junior developer or you know a
05:26
Senior developer hasn't seen seen the code in a while, so how would I describe these things for capybara? So readability means your feature test should be written as user stories like sort of
05:41
throwing back to the days of Cucumber feature files you want it to be something a stakeholder could read you want it to be sort of Clear as many technical details as possible even though. It's code you wanted to be sort you know Live in that Ruby essence of like very readable code
06:00
For maintainability you want Feature tests that are going to be able to grow and easily be refactored as your features and your in your product grows And for performance you want fast feedback either on your CI server You want to know if all your change if any of your changes broke some other ancillary part of the project or? When you're iterating on just a single feature you want to get be able to have
06:23
Fast feedback not to sort of sit there waiting for things to boot or waiting for things to fail so the goal for today is to go through each one of these and sort of describe sort of anti patterns and best practices that I've Developed over the past years that have helped give me confidence in a lot of excitement for adding feature tests
06:42
so readability The biggest thing I can say for readability is the same thing that was said about cucumber avoid any Raw selectors and feature specs as much as possible especially CSS classes I say especially CSS classes because I like to delineate CSS classes to just be purely used for styling
07:02
the biggest risk when sort of combining the two is that leveraging CSS classes either as a Test hook and as a styling in use for styling is that you're eventually more likely to sort of Overrun each other that if you have separate teams and designers changing CSS classes completely refactoring the markup
07:22
If they change the CSS class they're going to accidentally break the the the tests and maybe in several different places The other thing is the capybara DSL works really well when you use proper HTML semantics
07:40
And I'll go a bit more over that in a bit especially the forum DSL this means having labels with all your inputs properly marked up Last is you know kind of the summary of the two of these is it the user sort of described as something a
08:00
user could actually read and make sense of So to go over readability in the first case. Let's take a look at this quick feature test So in here, this is just a very simple sign-in test that creates a user Visits the sign-in page and then fills in the sign-in form, but there's one thing
08:22
I like I want to call out here. It's the fact that we're using the The input IDs to sign in I Don't think this is very human readable I don't think it makes sense from the perspective of a user story to have to look into the DOM find the element That has the matching ID and then set the value
08:42
It's also a big part sort of thing to go with this is also not very accessible So let's take a look at why that is so if you look at the template for this This is a simple form for two inputs email and password We'll see that we're specifying label false and sort of a common pattern
09:04
I've seen around a lot is to use placeholders in favor of labels Not only is this making the future test sort of less readable maybe more brittle to Changes in model naming column naming which are less likely likely it happened, but potentially so
09:24
It's all it's also not very accessible So you're limiting yourself to like a number of users who may be depending on screen readers or other assistive devices to use your application so Maybe an easy way around this is just to instead of removing the label will will hide it from view
09:42
Then the labels on the page Copy bar can find find the the corresponding label with this text value that's associated with that input and our test passes great Let me throw you a curveball Let's make this a JavaScript test, so it's actually using a JavaScript Driver, which is a more fully fledged browser under the hood that will behave more similarly to how a
10:08
Users browser would When we do this the test fails and this is because capybara defaults since version 2 2.0 to ignoring any any hitting hidden elements on the page
10:20
Going back to The accessibility part that's how your any users who are using like a screen reader will also experience the page they won't be able to find The input or here a readable understandable description of that input when they encounter it So a nice alternative to this is
10:42
Using a special sort of CSS hack to make the label not appear on the page Still appear visible to browsers so both screen readers and capybara in a JavaScript driver will both see it This accessible hide class I get from is essentially these declarations, and I get it from this
11:02
Snook's website where he discusses various ways of making content hidden on a page It's still accessible to screen readers, and I'll have my notes available later for people to review So we do this in our test pass and so you may be thinking well That was just a very simple kind of plain example, but it gets significantly more complicated when you think about any
11:24
applications that's using like accepts nested attributes or Any application you know any other application that may not be built on rails. That's using capybara and so forth where I'm sorry Not built on rails. That's using capybara for testing so even though this example is pretty simple
11:41
I have seen a lot worse examples or as people develop develop Helper methods in their tests to sort of generate the DOM ID that would be associated with like an accepts nested attributes Form input and it's just like a complete mess because you can't really tell what's going on or where it is or what it's Representing it at some point You're dealing with all this cognitive overhead of figuring out what this thing on the page is instead of just saying oh
12:02
that's the input for the expiration date So next I'm going to move on to this other feature test This is implementing a search for users in your Contacts being able to search by birthdate, and it's using a jQuery
12:24
Calendar picker so it requires JavaScript. I'm gonna note that We're leaving out the functionality of actually interacting with the date picker for later we will fill that out I just wanted to we'll slowly get there after we deal with some of the current issues with this
12:40
feature test But to get you on the same page as to like what we're seeing on the page. I took a little Screenshot, so that's effectively the behavior that we'll be wanting to test
13:02
So back to our tests. We see we have these two sort of Based on our premises earlier these two violations in our tests already. We're Using a raw CSS class in order to find the Button to open the calendar and manually click it the other is we're using the sort of
13:27
Complex Sizzle CSS selector to assert about content on the page while capybara understands sizzle it can sort of Lead to significantly more overhead in terms of understanding the spec you can do crazy things with sizzle
13:43
You could also equally do with capybara in a much more readable way in your fellow developers and stakeholders will thank you So let's tackle this first one. How do we make this easier like is there any way to use a click button? Like would this work if we pass a CSS class a click button unfortunately not
14:03
The if you dig deep enough you can find out What the allowed values are for click button? You have to dig all the way down to the XPath gem that capybara depends on which is how it builds all its Queries for finding elements in the DOM if you go all the way down you find
14:22
There is an XPath HTML button method that takes a locator and here you can see the locator can be any one of the buttons ID its Value or its title attribute and so title attribute is a pretty simple semantic way to Markup a button if it has no implicit text in it, so what we can do with the markup for our
14:46
Date picker input is add title attributes to the buttons that are used to hide open and close or reset the the calendar So once we add those we can change our spec to read much more nicely read much more fluently
15:04
Next let's try and break apart the sizzle Selector we're using the contains Filter to check first search result elements that contain the word John in them Well capybara provides us an option for this already with any of the have CSS
15:21
Have selector and find methods you can pass a text option And we'll get into it a bit more as to how you can find out what all those options are So let's quickly just change that to use the text option great Now we just have to deal with the way to get around the CSS class So if you look at our markup, what hook can we really use here other than
15:42
Either the Tag name of the element or any CSS classes Or just doing a slightly too vague like has content query which sort of can result in False positives because it checks the entire page I'm going to propose a convention. I have found to be very useful for you
16:03
Data Attributes according to the HTML spec custom data attributes are inherited to store custom data private to the page or application for which there are no appropriate Attributes or elements so this seems like a good fit We there's no there's no really good like tests took or like existing HTML market. That's what that's meaningful for us to use to
16:23
Find the element on the page to assert. It's there or not there or properties about it, so Let's add these two custom selectors with capybar you can add your own custom selectors and define whatever XPath or CSS you want to use to like you want to Reuse for that selector name
16:41
So here we're adding two data attributes data collection and data resource So we can mark up mark up our content with sort of data resource equals search result and search the page using using have select you know find model element In the name of the element search result since that's slightly a little bit verbose
17:05
Let's define some helpers for around that and then to make it even easier and much more sort of Readable in our test list of meta programs some other helpers on top of that so effectively and defining similar to
17:21
Sort of inspired by capybara. I'm defining wrappers around These selectors it defines such as selectors for the select element a field then defining Methods to assert that that element is there on the page, so this is the same as sort of
17:46
Select value from the label ID or other property of a select element and the same as saying the page should have the select label ID label or ID with the specific value and then
18:01
Providing name methods for easier reuse and just so the tests are less verbose so I add this data attribute to my markup and Now I can update my tests in this. I think this would you know read significantly better than It did before the benefits are we've decoupled CSS from
18:23
our test hook and we can also reuse these as hooks within a Application in JavaScript As well you can imagine sort of querying for a collection of elements using data collection and then filtering within that collection for data resource
18:41
Elements with the attribute data resource, so now let's fill in the date picker sort of digging a bit deeper That's not an intuitive thing to do with capybara This is what our date picker looks like In order to interact with this in order to change the date and pick one We'll want to be able to we'll want to change the month and the year in the selects
19:04
And then from from there once it's re-rendered. We want to click on the appropriate date in the right table cell So let's take a look at the market to see what we have to work with to see how you know Whether there's a label or ID or a name attribute that we could use to hook into The markup and interact with it with it in capybara
19:23
So the header has two select elements. They have no ID no name and No labels associated with them so the default DSL methods select blah from blah won't work for us additionally the anchor tags Dis include a number
19:42
And the numbers aren't guaranteed to be unique because if you look back we can see that there are two ones in the calendar Or two thirties in the calendar, so we can't be guaranteed that we'll be clicking the right one Or which one should we click the first or last one? So now I'd like to sort of dig dig a bit deeper into capybara's internals Let's look at how it manages to build this really
20:04
fluent DSL So let's introduce you if you aren't familiar with it already capybara element So whenever you run a fine query it what you're getting back in return is a capybara element instance It's a wrapper around the DOM element that you're representing and it provides you an interface for
20:22
Getting attributes or interacting with it in certain ways if it's a form input and All the DSL methods were familiar with their implemented in terms of these lower level primitives So for instance click button is defined Just this is defined just this way it finds a button with a locator and the options you provide to it and clicks on
20:41
It excuse me using capybara elements click method which simulates a click based on the driver. It's using So let's use capybara element to interact with the date picker So for the year for interacting with the year well Check the CSS class we see it's a select UI dash date picker your option
21:04
we want we want to Find the option within that select and use the select option method to tell the its parent select I'm the one that's selected right now We do the same for the month with a slightly different way to get the value and different selector
21:21
And then for picking the date we find This required some digging into sort of what unique what way I could uniquely query An anchor in the table, but we want the eight an anchor tag with UI state default That isn't a UI priority secondary UI priority secondary just means it's a date in the calendar
21:44
that's like the next month of the previous month and Then we match the first one that comes up we match first because you can imagine getting an ambiguous match Which capybara will throw an error for if you're picking the first it'll it could it will throw an ambiguous match because there's also the 10th
22:00
the 11th the 12th and so forth so now that we have these Methods let's put them in our test and so now we filled out that functionality for filling interacting with and filling out the date picker The problem with this is we're probably begin. We're probably gonna be doing this elsewhere in our tests It's likely to be used in other forms. It's not that great just to leave it in one place especially for how
22:25
convoluted and specific it is to To the jQuery date picker, so let's extract a helper method And extract a helper module to go with that so sorry let me back up for a moment What we're doing is we're extracting the choose date method which has a similar signature to the capybara select method it takes a
22:48
timestamp and a from attribute to That should indicate the label of the Or some text within the input that's associated with the date picker, and then effectively we just extract all the methods
23:06
All those calls into The module which we can include in our spec helper configuration Last I I think it's good whenever you add sort of this custom functionality that you add an additional check to make sure it's working
23:24
In this case for a search we do a full page reload We want to make sure that the value we entered is still on the page when the page reloads So let's add an assertion that the page has a date picker input with the right value that we initially input And so I'm going down this path to sort of introduce sort of another sort of lower level
23:42
aspect of capybara that Can really help to clean up a lot of your tests and avoid using custom avoid using hard coded selectors The have date picker inputs takes takes the label text finds the value formats it in the way, that's predetermined and then looks for a
24:03
Field with the right label text with the right value that is disabled because since we're using a date picker We don't want the user to accidentally type into the date field and change the date and submit an invalid value that won't parse It I was this was like kind of a surprise to me, I just randomly tried this one day
24:21
And it worked and then started digging into like where does this come from? What other options are there available and this comes from? capybara selector Capybara selector is what we added earlier when we defined our custom models element and model element Selectors it stores them internally and you can has an entire DSL for be able to modify them with different options
24:45
So it's a little bit small, but you can see on that line. It's defining a disabled option defaults to false. It's boolean And how to evaluate it when when evaluating the XPath so hooray we're done time to party
25:03
Next I'd like to get into performance sort of how do you make your tests a little bit faster? How do you? Get it get slightly quicker feedback. So a big way to get a lot of when out of Big performance when this use the within helper the within helper scopes
25:21
Can scope multiple assertions in in the same to the same part of the DOM that you're working with or visiting And avoids searching through the same sort of imagine you're making assertions about a model you've opened that's rendered at the bottom of the page if you just Make those same assertions over and over without scoping them your true every
25:44
Call that interact with an input or make an assertion starts at the top of the document And Trevor goes all the way down to look for it so for example We visit an addresses page. We expect the page to have 30 address elements using sort of the Pattern we established earlier we click a button add address that opens a modal
26:04
But each one of these call starts at the very top of the page when our modal is at the bottom of the page We can make it a bit more Performant by adding the within helper so that each one of these calls starts within the modal instead of having to go past all 30 addresses and whatever else is at the top of the page
26:22
There is a small caveat to within it can be somewhat of a gotcha sometimes imagine if you had a date picker input the jQuery date picker input binds itself inserts itself at the end of The but just before the closing body tag So if we're scoping within the modal dialog and we try and choose the date
26:44
It's gonna throw a capybara element not found even though like opening Attempting to open the date picker up or work We can't interact with it because it's on a different part of the page and just positioned on the part of the page We're interacting with This is a Just mentioning this as a note in case anyone sort of like gets stuck
27:02
Sees it working with if they run it in selenium, and they're just banging their head on like why it's not finding it It's just because you're within another element Another big win for performance, and I think also just in general for documentation Especially how much larger apps is to write your feature specs as QA scripts
27:22
I think it's I think people bring a lot of sort of the unit testing Methodology to feature tests where they don't really apply like one test for happy path one test for a sad path and like another test For sad path another test for this bug that we found That's really expensive Set up set up and tear down of every feature test can be pretty expensive
27:41
Especially if you have a large application the number of tip and especially for JavaScript tests Where it has to truncate the tables at the end of every test run? Additionally ever you know if you have to sign in or do a Convoluted process to get your user logged in and on the page they're interacting with if you do that five times You know relative to the amount of time you're spending actually testing you may be spending more time doing
28:00
Setup for all those tests, and you may actually be doing testing So this very tall bit of text is a single integration test from an application. I've worked on before And it goes through and sort of tries to bang out all the functionality That's available on that page all the edge cases for bugs to make sure that Everything's covered in one run, so I don't spend time visiting the site
28:21
You know creating user a dozen times visiting the sign-in page dealing with that overhead to every test So like for instance I have set up at the beginning I get on the page I want to go to I Start making assertions about an object that's already on the page I see if I can edit it see if I can cancel edit editing it to make sure that it correctly update updates the page I
28:47
Ensure within like the form to add something the right elements are disabled I make sure client validations are run. I check that the form is updated correctly when that when I submit it I'm sort of going through this long laundry list to sort of indicate like Be liberal with what you do on the page and just make sure it's well well
29:02
Documented and that's where a lot of these sort of earlier tips of making sure your testers readable as possible come in handy Because you can do these large form Integration tests and have them be very easy to understand and if you have to just add code comments So like this is really weird to be doing in this test But it's to sort of check this weird edge case, and that's perfect. I think that's perfectly fine
29:23
so an advanced use of Something really cool about capybara that I enjoy while working on some service-oriented Applications is that you can have the concept of a capybara window So you can be visiting two completely different apps within the same sort of capybara session
29:40
This is great for testing at service-oriented applications or maybe client-side applications where you have the client-side app in one repository or a different folder in the same repository than the Server that's running it and the server doesn't even need to be rails or any anything Ruby based none of it does and just as a quick example of this imagine I have a
30:01
feature test You know the process that's running capybara isn't linked to either the Client-side application that is the API or the CMS that is like the the store management app I'm just running this as a process on its own There's been some setups process either on CI or locally on my machine to make sure those two processes are running
30:24
I've Configured such that I don't have to worry about These being hard-coded or for Demonstrative purposes we can just leave them that way I Can open windows to each of these app each of these applications using window open by window open by you just sort of
30:41
Run some commands and it opens a window and hands you passes your handle to it Then using within window you can interact with that window. So in this test, I'm Visiting the CMS app and creating a product with the name foo like most of these helpers are sort of just sort of implementation details Then with them within the store window, I'm visiting the
31:02
Base API our own making sure that that product exists So this could be testing that from a CMS that can send in and as an admin Create a product enter its details and then all the process that go that's involved with moving that to another database And making it appear in the API and properly rendered in the UI That's all working with just like a couple lines of code and some initial setup
31:24
then when I go back to the CMS app, I mark the product is out of stock go back to the Store app and make sure that it's not visible anymore. And so this is sort of an example of you know If your goal is SOA or client-side application with separation of concerns
31:40
You can still use capybara to sort of make sure everything's coming together correctly And the nice thing is this can just all live on its own repository with its own configuration and setup Is what we did on a project I worked on a previous company and it was Pretty useful to just have that as sort of documentation of everything So yeah, so that's everything I have thank you for your time