Use CodeCeption assertion in conditional (if) statement

11,628

Solution 1

I had this same issue. Although it's not ideal, you can do this:

try {
    $I->see('message');
    // Continue to do this if it's present
    // ...
} catch (Exception $e) {
    // Do this if it's not present.
    // ...
}

Solution 2

In tests/_support/AcceptanceHelper.php add additional method

function seePageHasElement($element)
{
    try {
        $this->getModule('WebDriver')->_findElements($element);
    } catch (\PHPUnit_Framework_AssertionFailedError $f) {
        return false;
    }
    return true;
}

Then to test in your acceptance test use:

if ($I->seePageHasElement("input[name=address]")) {
    $I->fillField("input[name=address]", "IM");
}

Solution 3

ULTIMATE SOLUTION!

Finally Codeception now has the function performOn, wich does exactly what I asked for!!

[Version 2.2.9]

http://codeception.com/docs/modules/WebDriver#performOn

Answering my example:

$I->performOn('.message', ['click' => '#button_close'], 30);

Waits up to 30 seconds to see the element with class='message', then click the element with id='button_close'.

Solution 4

You can use a workaround like this or similar combinations:

$tmp = $I->grabTextFrom('SELECTOR');
if ($tmp == 'your text') {

$I->click('button_close');

}

Solution 5

Codeception now has tryTo..., e.g, tryToSee() trytoClick(), etc., so there's no need for a Try/Catch block. I find it more readable than performOn().

You need to enable it with this in acceptance.suite.yml or codeception.yml:

# enable conditional $I actions like $I->tryToSee()
step_decorators:
    - \Codeception\Step\TryTo
    - \Codeception\Step\ConditionalAssertion`

You can click on something that may or may not be there with:

$I->tryToClick('#save_button`);

If there's no button, the code goes on with no error message. This could also be used to click on the node to expand a section of a tree before examining it, but only if that section is closed (there should always be a class that's only there when it's closed).

Another way to go is in an if statement. The tryTo... methods all return true on success and false on failure, so you can do this, which some might consider clearer than the above (no error will be thrown):

if ($I->tryToSee('some_locator')) {
    $I->click('some_locator');
}

This form is also useful if there is a sequence of actions you want to perform based on a condition, the else is optional.

if ($I->tryToSee('some_locator')) {
    $I->fillField('username', 'myname');
    $I->fillfield('password', 'mypassword);
    $I->click('Submit');
} else {
   /* Do something else */
}
Share:
11,628

Related videos on Youtube

Borjovsky
Author by

Borjovsky

Programming: Graduated in 2012. Languages: HTML CSS PHP MySQL React VueJS Java (favorite) OOP & TDD (how can someone code without it?) Editors: VSCode Sublime Vim (learning the navigation stuff...) Chrome extensions to boost productivity: Dark Reader AdBlocker Ultimate GoogleDocks Offline Marinara Pomodoro Assistant Noisli Plus for Trello React Developer Tools Iridium for Youtube Reverse Playlist for Youtube Video Speed Controller Keyboard: 90+ words/min (goal: 130) KBParadise V60+ with CherryMX Brown keys, with 40-A silencer O-rings Chess: Studying since 2006. Teaching since 2014. Favorite Masters: Susan Polgar Anatoly Karpov Garry Kasparov Bobby Fischer Josh Waitzkin Igor Smirnov (positional style, in general)

Updated on June 27, 2022

Comments

  • Borjovsky
    Borjovsky almost 2 years

    I'm totally new with CodeCeption.

    I want to do an action/assertion depending on another assertion result, like this:

    if ($I->see('message')){
    
        $I->click('button_close');
    
    }
    

    Is something like that possible? I tried, but doesn't work. Probably the assertion result doesn't apply to IF, but is there any alternative?

    Thanks in advance!

    IMPORTANT UPDATE:

    Finally Codeception now has the function performOn!! http://codeception.com/docs/modules/WebDriver#performOn

  • Borjovsky
    Borjovsky over 9 years
    That idea is fine, but there is a problem: If the 'SELECTOR' is not present (no 'message' in my example), the assertion fails and the test suite stops. So, one assertion must depend on another assertion. But thank you anyway!
  • Borjovsky
    Borjovsky over 8 years
    Great!! This solution is better than mine! Much more flexible, and looks better. I didn't know that try/catch could work. Thank you very much!
  • DAB
    DAB over 8 years
    np! One thing to note - it won't show the test as failed, but if you do have a failure after that it may add an additional error line that can be confusing. But if the rest of the tests pass it won't complain.
  • Borjovsky
    Borjovsky over 8 years
    Thanks DAB! I guess I'll be able to deal with such situations with the catch.
  • Naktibalda
    Naktibalda almost 7 years
    This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From Review
  • Naktibalda
    Naktibalda almost 7 years
    What do you mean with "This does not work"? Do you get an error? Please be specific.
  • iamuser2
    iamuser2 almost 7 years
    @Naktibalda i mean by "This does not work"? is that the solution doesnot work for me as i had the same case. I figured out the right solution that worked for me & i have posted it so that needy can be benefited.
  • Naktibalda
    Naktibalda almost 7 years
    A problem with your solution is that _findElements doesn't throw PHPUnit_Framework_AssertionFailedError exception when the element does not exist, it returns an empty array.
  • iamuser2
    iamuser2 almost 7 years
    @Naktibalda ur right !! That part isnot handled.I provide the solution to fulfill the need of using 'IF' statement to compare something and do the required task if its true. And i didnot find any working solution for using "IF" condition in my codeception code.
  • Borjovsky
    Borjovsky over 6 years
    That's Matija's solution.
  • Julie Pixie
    Julie Pixie over 3 years
    This didn't do anything for me, my tests still fail if the element isn't present. Anyone have any follow ups?