Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
For better compatibility with existing Simpletests we should try to provide assertFieldByXPath(), but mark it as deprecated. That way we need to change fewer parts of a test when converting from Simpletest to BrowserTestBase.
Proposed resolution
Implement the method, test it in BrowserTestBaseTest.
Remaining tasks
Patch.
User interface changes
None.
API changes
None.
Data model changes
None.
Comment | File | Size | Author |
---|---|---|---|
#87 | assert-field-xpath-2784537-87.patch | 8.13 KB | klausi |
Comments
Comment #2
klausipatch.
Comment #3
mpdonadioProbably also want assertNoFieldByXpath(), too?
Comment #4
mpdonadioMention FormattableMarkup instead?
Otherwise looks good, but I would vote for also adding assertNoFieldByXpath(). PhpStorm reports 49 usages in 8.2.x.
Comment #5
dawehnerAdded a small issue: #2784677: Move core/modules/simpletest/tests/src/Functional/BrowserTestBaseTest.php to core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php
Comment #6
dawehnerIMHO we should simply use sprintf or string concatenation. We are not creating markup here.
Comment #7
klausiyes, assertNoFieldByXpath() is missing, we should do that here as well.
Ah yes, the comment for $message is just copy pasta from Simpletest. Of course you can just use string concatenation for messages.
Comment #8
mpdonadioGetting a bit off topic here, but we aren't terribly consistent about this since all of the SafeMarkup related changes went down. I had a patch get pushed back with the request to use FormattableMarkup for a message a little while ago. Personally, I think we should either add a BTB::format() method (via a trait) or add an extra $args argument to the assertion methods that take a $message, and either would just do a simple `$message = strtr($message, $args);` I think I may have even made an issue about this, and then forgotten to follow through on it.
Comment #9
klausiAdded assertNoFieldByXPath() and improved comments to not even mention SafeMarkup and friends, like we do on the other AssertLegacyTrait methods.
Comment #10
dawehnerThank you
Comment #12
klausiSimple reroll, no other changes.
Comment #13
dawehnerBack to RTBC
Comment #15
klausiRandom test fail, queuing that test again.
Comment #17
mpdonadioTwo good test runs after the update spurious. Back to RTBC per #13.
Comment #18
catchThese are 1-1 copies from Simpletest's assertFieldByXPath()/assertNoFieldByXPath() - could we not move them into a shared trait then use that in both AssertContentTrait and AssertLegacyTrait?
Comment #19
catchComment #20
dawehnerYes and no.
This is using a different function than the simpletest alternative.
Comment #21
catchWell I mentioned assertFieldByXpath and assertNoFieldByXpath() not assertNoFieldChecked() ;)
Comment #22
dawehnerPersonally I'm not convinced that this is worth the hassle.
Comment #24
mpdonadioThis should fix the fails.
Comment #26
mpdonadioThe problem is that $field is a \SimpleXMLElement when run from WTB and a \Behat\Mink\Element\NodeElement when run from a BTB. Not sure if there is a common way to handle these?
Comment #27
dawehnerBTB and WTB are really two separate things. Let's not try to share code for the sake of it.
Here is a reupload of #12 with a RTBC
Comment #29
mglamanRequed #27. Pulled latest 8.3.x and ran
\Drupal\FunctionalTests\BrowserTestBaseTest
without failures.Comment #30
mglamanThe test had passed. Must have been a hiccup, putting back to RTBC as dawehner had done in #27!
Comment #31
mpdonadioThe fail in #27 was in the new test:
which is a bit of a warning sign.
The attached fixes a few nits, but I don't think they should have caused this fail (since PHP method names are case insensitive for some odd reason).
Comment #32
dawehnerAH good observation!
Comment #33
mpdonadioThe PHP 5.6 fails are #2762549: Drupal\field\Tests\Update\FieldUpdateTest, Drupal\views\Tests\Update\EntityViewsDataUpdateTest and Drupal\comment\Tests\CommentFieldsTest fail on 8.1.x. I can't make BrowserTestBaseTest fail to reproduce the bot fail to see what actually happened.
Comment #34
klausiSo the random test fails are already covered in another issue and this issue does not affect them in any way.
Patch still looks good, back to RTBC.
Comment #36
mpdonadioSimpletest.Drupal\simpletest\Tests\SimpleTestBrowserTest
✓ - setUp
✓ - testInternalBrowser
✓ - testUserAgentValidation
✗
testTestingThroughUI
fail: [Other] Line 143 of core/modules/simpletest/src/Tests/SimpleTestBrowserTest.php:
"0 fails, 0 exceptions" found
This is a random failed covered in #2476139: Fix UI test fail in SimpleTestBrowserTest and/or #2605664: [Needs change record updates] Align TestDiscovery and bootstrap.php's non-permissive loading of PSR-4 namespaces for traits
Comment #37
mpdonadioRandom fail covered in a different issue. Back to RTBC.
Comment #39
klausiRandom test fail again, back to RTBC.
Comment #40
alexpottThere's no test coverage of this method and given it is the most complex it probably requires it the most.
Comment #41
mpdonadioThis needs a reroll b/c #2773733: Fix AssertLegacyTrait::assert(No)Text to handle html encoded strings (part 3).
While I did the reroll, I split testLegacyAsserts() so it wouldn't become a mega-method (the main merge conflict was here), and also fixed some small case problems.
Will see if I can address #40 next. It is implicitly tested since assertFieldsByValue is called by assertFieldByXPath(), but see if I canl make this more explicit.
Comment #42
mpdonadioThis should cover all of the TRUE paths through assertFieldsByValue().
Comment #43
klausiThank you, the changes look good!
We already have assertNoFieldChecked(), removing from the title.
Comment #45
klausiI have no idea why the patch failed testing. Works as expected locally for me. Retesting.
Comment #46
klausiNow working as advertised on the testbot, back to RTBC.
Comment #47
klausiSo this issue introduces a random test fail, it just happened again in #2770921: Feb 21st: Convert chunk of WTB to BTB by just moving classes, changing use statements adding traits. We need to find out what exactly goes wrong here.
Comment #49
mpdonadioI did
and it ran overnight w/o a fail. So, we either have an environment problem on the bots or something weird is going on with this test and concurrency.
Comment #50
klausiLet's try some debugging on the testbot where we print out the HTML body to see what does not match.
Comment #52
klausiAha, we are using BrowserTestBaseTest in SimpleTestBrwoserTest for Simpletest UI testing. Which might be bad if our BrowserTestBaseTest class grows larger and larger. Let's use Breadcrumb404Test instead.
No idea about the fail on Postrgres with testEntityReferenceAutocompleteWidget().
Comment #53
dawehnerIMHO The right thing is to add its own dedicated test, just for that. I think there should be a dedicated rule for tests, that there should be test fixtures, instead of reusing other code, as you know, tests for example aren't an API, so you should not rely on their existence.
IMHO this change is also unrelated.
Comment #54
klausiThe change is related to this issue because we are making BrowserTestBaseTest longer, which causes random test fails in SimpleTestBrowserTest. Agreed that SimpleTestBrowserTest should use a dedicated test fixture, let's do that in a separate issue.
Removing the debug statements from the test, let's see if we still get random fails.
Comment #55
klausiYay, no random test failures anymore. I'll queue another round just to make sure.
Opened #2820442: SimpleTestBrowserTest has random fails when BrowserTestBaseTest gets larger.
Comment #56
dawehnerSorry for maybe being a bit annoying here :(
It would be nice to understand where this is coming from, so let's open up a follow up for itself: #2820458: SimpleTestBrowserTest is really fragile
Comment #58
klausiRerolled, no other changes.
Comment #59
klausiUnrelated test fails of EntityReferenceAutocompleteWidgetTest on Postgres, queuing that again.
Comment #60
dawehnerThat's still RTBC
Comment #61
catchLooks like an unrelated random fail here: https://www.drupal.org/pift-ci-job/524001 - sent for re-test.
Comment #62
mpdonadio#61, actually this is really odd and possibly a clue.
is this assertion
though that test is currently a WTB (the particular assertion is a recent addition, #2811725: Error when render Datetime Range field: Error: Unsupported operand types). The Mink and SimpleXML XPath guts aren't compatible (see one of the earlier patches where we tried to reuse the trait between BTB and WTB). So, I am wondering if either the classloader or opcache is having problems with the trait and using the wrong one, or of if the XML library that evenutally gets called (libxml?) isn't 100% reentrant.
Comment #63
catchHmm interesting. Moving back to CNR, this is worth some investigating, although if it's a real issue that's pretty horrible.
Comment #64
mpdonadioAre we getting bit by #2605664: [Needs change record updates] Align TestDiscovery and bootstrap.php's non-permissive loading of PSR-4 namespaces for traits?
Comment #66
mpdonadiohttps://www.drupal.org/pift-ci-job/525542
Same type of prob, but in the BTB version
I wonder if we can test this hypothesis by adding something like
and the SimpleXML equivalent in the appropriate places?
Comment #67
mpdonadioExperiment. Going to hog a few bots. Did we dig through the logs to see if this is one particular bot, or a mix of them?
Comment #68
klausiGood news: I could reproduce the BrowserTestBaseTest fail
when the role name of the created user contains a pipe (|). So this is yet another instance of #2808085: Pipe char in locators break Mink and Symfony element search.Bad news: I have no idea about the random DateTime test fail.
Comment #69
klausiUpdate: not the pipe character is at fault but the ordering of the user table on the /admin/people page. Sometimes the newly created user is in the first row because the table is sorted by user creation date, which can be almost at the same time as the admin user was created.
This is really my fault because I was lazy and just used an existing admin page. Instead we should create a dedicated test page with a table on it with static content for this test. Sorry for wasting everybody's time.
Comment #70
klausiNow with dedicated test form page. Interdiff is against #58.
Comment #71
klausiTestbot is all green in all environments, queuing another full round to be sure.
Comment #72
dawehnerDeterministic and explicit test code, yeah! nitpick: There is a single
array
which sneaked in.Comment #73
klausiFixed long array syntax.
Comment #74
dawehnerCool, thank you!
Comment #76
joelpittetTestbot failure, resetting status due to https://www.drupal.org/node/2828045
Comment #78
klausiStill green, not sure what the bot complained about? Will queue all environments again just to be sure.
Comment #79
xjmWow, this issue has more than its fair share of weird test problems, which always makes me nervous for testing improvement issues. When we see unexplained test failures, we should always try to explain them (in general, but also especially when we are actually patching the testing system). Looking them over:
So I think that accounts for all of them. Good gracious.
I'll also retest everything again.
Comment #80
xjmThe retests passed, which is good. Phew.
Patch looks great BTW.
Comment #82
klausiAnd more fails we can explain with other issues:
https://www.drupal.org/pift-ci-job/542381 is #2830485: \Drupal\Tests\outside_in\FunctionalJavascript\OutsideInBlockFormTest fails randomly
https://www.drupal.org/pift-ci-job/542382 is #2832013: CommentResourceTestBase::testPostDxWithoutCriticalBaseFields() always fails on PHP 5.6 & MySQL 5.5 (works fine on other PHP versions)
https://www.drupal.org/pift-ci-job/542377 is #2806697: Random fail for AlreadyInstalledException
https://www.drupal.org/pift-ci-job/542379 I have not seen issues for that one yet, but looking unrelated to this issue.
Comment #83
xjmYeah https://www.drupal.org/pift-ci-job/542379 is #2828559: UpdatePathTestBase tests randomly failing.
Comment #85
klausiSQLite is broken on HEAD also, back to RTBC.
Comment #86
alexpottI think we should include info about #2767655: Allow WebAssert to inspect also hidden fields and point to the new methods on assertSession since if you are using this methods a straight conversion using assert session's field methods might not work.
Comment #87
klausi@alexpott: assertFieldByXpath() takes an XPath expression as parameter. fieldExists() and hiddenFieldExists() take id|name|label|value as parameter. You can't convert your old assertFieldByXpath() calls to those methods.
assertFieldByXpath() is a very unfortunate name in old Simpletest. It is not specific at all to form fields, it works on any HTML element. The direct replacement to assertFieldByXpath() is executing the XPath query directly in the test and then working with the resulting DOM nodes.
You are right that the comment on assertNoFieldByXPath() is misleading, brought that into sync with assertFieldByXPath().
Comment #88
claudiu.cristeaLooks good. Only a nit regarding the deprecation message.
It cannot be removed exactly in 9.0.0. Either "in 9.0.x" or "before 9.0.0".
Comment #89
klausi@claudiu.cristea: that deprecation message is used already in many other places, so should be fine. The method will be removed in a 9.0.x branch, but to developers only releases are interesting.
Comment #90
claudiu.cristeaLet the committers decide.
Comment #92
klausiRandom test fail, already handled in #2828559: UpdatePathTestBase tests randomly failing.
Comment #94
mpdonadioMore #2828559: UpdatePathTestBase tests randomly failing failures...
Comment #95
xjmAssigning to @alexpott for review based on #86 and #87.
Comment #97
klausiAnd again the same random #2828559: UpdatePathTestBase tests randomly failing failures, back to RTBC.
Comment #98
alexpottCommitted 3cd6934 and pushed to 8.3.x. Thanks!
@klausi thanks for considering and answering my questions.
Comment #101
klausiFollow-up: #2857725: Improve assertNoFieldByName() compatibility for empty strings