New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Division by zero in Step when maxLength < 0 #3922

Closed
mlespiau opened this Issue Jan 16, 2017 · 5 comments

Comments

Projects
None yet
3 participants
@mlespiau

mlespiau commented Jan 16, 2017

What are you trying to achieve?

I'm trying to use acceptPopup or cancelPopup from Codeception WebDriver to cancel or accept a popup in an Acceptance test.

What do you get instead?

The test case fails with no errors no related debug information.

Details

  • Codeception version:
  • PHP Version: PHP 5.6.27
  • Operating System: Alpine Linux Docker Image
  • Installation type: Composer
  • List of installed packages (composer show)
behat/gherkin                        v4.4.5  Gherkin DSL parser for PHP 5.3
codeception/codeception              2.2.7   BDD-style testing framework
doctrine/annotations                 v1.3.1  Docblock Annotations Parser
doctrine/cache                       v1.6.1  Caching library offering an object-oriented API for many cache backends
doctrine/collections                 v1.3.0  Collections Abstraction library
doctrine/common                      v2.7.2  Common Library for Doctrine projects
doctrine/dbal                        v2.5.7  Database Abstraction Layer
doctrine/doctrine-bundle             1.6.6   Symfony DoctrineBundle
doctrine/doctrine-cache-bundle       1.3.0   Symfony Bundle for Doctrine Cache
doctrine/inflector                   v1.1.0  Common String Manipulations with regard to casing and singular/plural rules.
doctrine/instantiator                1.0.5   A small, lightweight utility to instantiate objects in PHP without invoking their constructors
doctrine/lexer                       v1.0.1  Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.
doctrine/orm                         v2.5.6  Object-Relational-Mapper for PHP
facebook/webdriver                   1.3.0   A PHP client for WebDriver
guzzlehttp/guzzle                    6.2.2   Guzzle is a PHP HTTP client library
guzzlehttp/promises                  v1.3.1  Guzzle promises library
guzzlehttp/psr7                      1.3.1   PSR-7 message implementation
incenteev/composer-parameter-handler v2.1.2  Composer script handling your ignored parameter file
jdorn/sql-formatter                  v1.2.17 a PHP SQL highlighting library
monolog/monolog                      1.22.0  Sends your logs to files, sockets, inboxes, databases and various web services
myclabs/deep-copy                    1.5.5   Create deep copies (clones) of your objects
paragonie/random_compat              v2.0.4  PHP 5.x polyfill for random_bytes() and random_int() from PHP 7
phpdocumentor/reflection-common      1.0     Common reflection classes used by phpdocumentor to reflect the code structure
phpdocumentor/reflection-docblock    3.1.1   With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.
phpdocumentor/type-resolver          0.2.1
phpspec/prophecy                     v1.6.2  Highly opinionated mocking framework for PHP 5.3+
phpunit/php-code-coverage            4.0.4   Library that provides collection, processing, and rendering functionality for PHP code coverage information.
phpunit/php-file-iterator            1.4.2   FilterIterator implementation that filters files based on a list of suffixes.
phpunit/php-text-template            1.2.1   Simple template engine.
phpunit/php-timer                    1.0.8   Utility class for timing
phpunit/php-token-stream             1.4.9   Wrapper around PHP's tokenizer extension.
phpunit/phpunit                      5.4.8   The PHP Unit Testing framework.
phpunit/phpunit-mock-objects         3.4.3   Mock Object library for PHPUnit
psr/cache                            1.0.1   Common interface for caching libraries
psr/http-message                     1.0.1   Common interface for HTTP messages
psr/log                              1.0.2   Common interface for logging libraries
sebastian/code-unit-reverse-lookup   1.0.0   Looks up which function or method a line of code belongs to
sebastian/comparator                 1.2.2   Provides the functionality to compare PHP values for equality
sebastian/diff                       1.4.1   Diff implementation
sebastian/environment                2.0.0   Provides functionality to handle HHVM/PHP environments
sebastian/exporter                   1.2.2   Provides the functionality to export PHP variables for visualization
sebastian/global-state               1.1.1   Snapshotting of global state
sebastian/object-enumerator          1.0.0   Traverses array structures and object graphs to enumerate all referenced objects
sebastian/recursion-context          1.0.2   Provides functionality to recursively process PHP variables
sebastian/resource-operations        1.0.0   Provides a list of PHP built-in functions that operate on resources
sebastian/version                    2.0.1   Library that helps with managing the version number of Git-hosted PHP projects
sensio/distribution-bundle           v5.0.18 Base bundle for Symfony Distributions
sensio/framework-extra-bundle        v3.0.19 This bundle provides a way to configure your controllers with annotations
sensio/generator-bundle              v3.1.2  This bundle generates code for you
sensiolabs/security-checker          v4.0.0  A security checker for your composer.lock
swiftmailer/swiftmailer              v5.4.5  Swiftmailer, free feature-rich PHP mailer
symfony/monolog-bundle               v3.0.3  Symfony MonologBundle
symfony/phpunit-bridge               v3.2.2  Symfony PHPUnit Bridge
symfony/polyfill-apcu                v1.3.0  Symfony polyfill backporting apcu_* functions to lower PHP versions
symfony/polyfill-intl-icu            v1.3.0  Symfony polyfill for intl's ICU-related data and classes
symfony/polyfill-mbstring            v1.3.0  Symfony polyfill for the Mbstring extension
symfony/polyfill-php56               v1.3.0  Symfony polyfill backporting some PHP 5.6+ features to lower PHP versions
symfony/polyfill-php70               v1.3.0  Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions
symfony/polyfill-util                v1.3.0  Symfony utilities for portability of PHP codes
symfony/swiftmailer-bundle           v2.4.2  Symfony SwiftmailerBundle
symfony/symfony                      v3.2.2  The Symfony PHP framework
twig/twig                            v1.31.0 Twig, the flexible, fast, and secure template language for PHP
webmozart/assert                     1.2.0   Assertions to validate method input/output with nice error messages.
  • Suite configuration:
class_name: AcceptanceTester
modules:
    enabled:
        - WebDriver:
            url: 'http://opencats/' # put your local url
            host: selenium
            browser: firefox
        - AppBundle\Helper\Acceptance
@mlespiau

This comment has been minimized.

Show comment
Hide comment
@mlespiau

mlespiau Jan 16, 2017

I've narrowed down the cause by capturing Exception and it's a Division by 0 error in Step.php class in the following line $allowedLength = floor(($maxLength - $argumentCount + 1) / $argumentCount);:

    public function getArgumentsAsString($maxLength = 200)
    {
        $arguments = $this->arguments;
        $argumentCount = count($arguments);
        $totalLength = $argumentCount - 1; // count separators before adding length of individual arguments
        ...
        if ($totalLength > $maxLength) {
        ...
            $allowedLength = floor(($maxLength - $argumentCount + 1) / $argumentCount);
        ...
        }
        ...
}

If I follow the executions this is because the acceptPopup and closePopup do not receive any parameters. I wonder if there are any other test methods facing the same issue.

EDIT: The problem seems to be that the number of arguments (maxLimit) is coming in negative numbers, which is not the intended behaviour.

EDIT: In my case the negative numbers are coming from here: Codeception\Subscriber\Console.php:

 #0 /var/www/code/vendor/codeception/codeception/src/Codeception/Step.php(237): Codeception\Step->getArgumentsAsString(-18)
  #1 /var/www/code/vendor/codeception/codeception/src/Codeception/Step.php(218): Codeception\Step->getHumanizedArguments(-18)
  #2 /var/www/code/vendor/codeception/codeception/src/Codeception/Subscriber/Console.php(322): Codeception\Step->toString(-7)
  #3 /var/www/code/vendor/codeception/codeception/src/Codeception/Subscriber/Console.php(304): Codeception\Subscriber\Console->printStep(Object(Codeception\Step\Condition))
  #4 [internal function]: Codeception\Subscriber\Console->beforeStep(Object(Codeception\Event\StepEvent), 'step.before', Object(Symfony\Component\EventDispatcher\EventDispatcher))
  #5 /var/www/code/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/EventDispatcher.php(174): call_user_func(Array, Object(Codeception\Event\StepEvent), 'step.before', Object(Symfony\Component\EventDispatcher\EventDispatcher))
  #6 /var/www/code/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/EventDispatcher.php(43): Symfony\Component\EventDispatcher\EventDispatcher->doDispatch(Array, 'step.before', Object(Codeception\Event\StepEvent))
  #7 /var/www/code/vendor/codeception/codeception/src/Codeception/Scenario.php(78): Symfony\Component\EventDispatcher\EventDispatcher->dispatch('step.before', Object(Codeception\Event\StepEvent))
  #8 /var/www/code/src/AppBundle/tests/_support/_generated/AcceptanceTesterActions.php(268): Codeception\Scenario->runStep(Object(Codeception\Step\Condition))
  #9 /var/www/code/src/AppBundle/tests/_support/AcceptanceTester.php(61): AppBundle\AcceptanceTester->amOnPage('/index.php?m=lo...')
  #10 /var/www/code/src/AppBundle/tests/_support/AcceptanceTester.php(53): AppBundle\AcceptanceTester->iLoginAs('admin', 'admin')
  #11 [internal function]: AppBundle\AcceptanceTester->iAmAuthenticatedAs('Administrator')
  #12 /var/www/code/vendor/codeception/codeception/src/Codeception/Test/Gherkin.php(130): call_user_func_array(Array, Array)
  #13 /var/www/code/vendor/codeception/codeception/src/Codeception/Test/Gherkin.php(88): Codeception\Test\Gherkin->runStep(Object(Behat\Gherkin\Node\StepNode))
  #14 /var/www/code/vendor/codeception/codeception/src/Codeception/Test/Test.php(90): Codeception\Test\Gherkin->test()
  #15 /var/www/code/vendor/phpunit/phpunit/src/Framework/TestSuite.php(753): Codeception\Test\Test->run(Object(PHPUnit_Framework_TestResult))
  #16 /var/www/code/vendor/codeception/codeception/src/Codeception/PHPUnit/Runner.php(98): PHPUnit_Framework_TestSuite->run(Object(PHPUnit_Framework_TestResult))
  #17 /var/www/code/vendor/codeception/codeception/src/Codeception/SuiteManager.php(162): Codeception\PHPUnit\Runner->doEnhancedRun(Object(Codeception\Suite), Object(PHPUnit_Framework_TestResult), Array)
  #18 /var/www/code/vendor/codeception/codeception/src/Codeception/Codecept.php(183): Codeception\SuiteManager->run(Object(Codeception\PHPUnit\Runner), Object(PHPUnit_Framework_TestResult), Array)
  #19 /var/www/code/vendor/codeception/codeception/src/Codeception/Codecept.php(152): Codeception\Codecept->runSuite(Array, 'acceptance', 'job-orders.feat...')
  #20 /var/www/code/vendor/codeception/codeception/src/Codeception/Command/Run.php(282): Codeception\Codecept->run('acceptance', 'job-orders.feat...')
  #21 /var/www/code/vendor/symfony/symfony/src/Symfony/Component/Console/Command/Command.php(262): Codeception\Command\Run->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
  #22 /var/www/code/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php(826): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
  #23 /var/www/code/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php(189): Symfony\Component\Console\Application->doRunCommand(Object(Codeception\Command\Run), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
  #24 /var/www/code/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php(120): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
  #25 /var/www/code/vendor/codeception/codeception/src/Codeception/Application.php(103): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), NULL)
  #26 /var/www/code/vendor/codeception/codeception/codecept(34): Codeception\Application->run()
  #27 {main}

I'm proposing a small change that will make this problem go away, but I do not know what the right approach is. It seems the logic for limiting the amount of characters displayed on the console is all over the place!!!

My simple "fix":

$allowedLength = floor(($maxLength - $argumentCount + 1) / max($argumentCount, 1));

mlespiau commented Jan 16, 2017

I've narrowed down the cause by capturing Exception and it's a Division by 0 error in Step.php class in the following line $allowedLength = floor(($maxLength - $argumentCount + 1) / $argumentCount);:

    public function getArgumentsAsString($maxLength = 200)
    {
        $arguments = $this->arguments;
        $argumentCount = count($arguments);
        $totalLength = $argumentCount - 1; // count separators before adding length of individual arguments
        ...
        if ($totalLength > $maxLength) {
        ...
            $allowedLength = floor(($maxLength - $argumentCount + 1) / $argumentCount);
        ...
        }
        ...
}

If I follow the executions this is because the acceptPopup and closePopup do not receive any parameters. I wonder if there are any other test methods facing the same issue.

EDIT: The problem seems to be that the number of arguments (maxLimit) is coming in negative numbers, which is not the intended behaviour.

EDIT: In my case the negative numbers are coming from here: Codeception\Subscriber\Console.php:

 #0 /var/www/code/vendor/codeception/codeception/src/Codeception/Step.php(237): Codeception\Step->getArgumentsAsString(-18)
  #1 /var/www/code/vendor/codeception/codeception/src/Codeception/Step.php(218): Codeception\Step->getHumanizedArguments(-18)
  #2 /var/www/code/vendor/codeception/codeception/src/Codeception/Subscriber/Console.php(322): Codeception\Step->toString(-7)
  #3 /var/www/code/vendor/codeception/codeception/src/Codeception/Subscriber/Console.php(304): Codeception\Subscriber\Console->printStep(Object(Codeception\Step\Condition))
  #4 [internal function]: Codeception\Subscriber\Console->beforeStep(Object(Codeception\Event\StepEvent), 'step.before', Object(Symfony\Component\EventDispatcher\EventDispatcher))
  #5 /var/www/code/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/EventDispatcher.php(174): call_user_func(Array, Object(Codeception\Event\StepEvent), 'step.before', Object(Symfony\Component\EventDispatcher\EventDispatcher))
  #6 /var/www/code/vendor/symfony/symfony/src/Symfony/Component/EventDispatcher/EventDispatcher.php(43): Symfony\Component\EventDispatcher\EventDispatcher->doDispatch(Array, 'step.before', Object(Codeception\Event\StepEvent))
  #7 /var/www/code/vendor/codeception/codeception/src/Codeception/Scenario.php(78): Symfony\Component\EventDispatcher\EventDispatcher->dispatch('step.before', Object(Codeception\Event\StepEvent))
  #8 /var/www/code/src/AppBundle/tests/_support/_generated/AcceptanceTesterActions.php(268): Codeception\Scenario->runStep(Object(Codeception\Step\Condition))
  #9 /var/www/code/src/AppBundle/tests/_support/AcceptanceTester.php(61): AppBundle\AcceptanceTester->amOnPage('/index.php?m=lo...')
  #10 /var/www/code/src/AppBundle/tests/_support/AcceptanceTester.php(53): AppBundle\AcceptanceTester->iLoginAs('admin', 'admin')
  #11 [internal function]: AppBundle\AcceptanceTester->iAmAuthenticatedAs('Administrator')
  #12 /var/www/code/vendor/codeception/codeception/src/Codeception/Test/Gherkin.php(130): call_user_func_array(Array, Array)
  #13 /var/www/code/vendor/codeception/codeception/src/Codeception/Test/Gherkin.php(88): Codeception\Test\Gherkin->runStep(Object(Behat\Gherkin\Node\StepNode))
  #14 /var/www/code/vendor/codeception/codeception/src/Codeception/Test/Test.php(90): Codeception\Test\Gherkin->test()
  #15 /var/www/code/vendor/phpunit/phpunit/src/Framework/TestSuite.php(753): Codeception\Test\Test->run(Object(PHPUnit_Framework_TestResult))
  #16 /var/www/code/vendor/codeception/codeception/src/Codeception/PHPUnit/Runner.php(98): PHPUnit_Framework_TestSuite->run(Object(PHPUnit_Framework_TestResult))
  #17 /var/www/code/vendor/codeception/codeception/src/Codeception/SuiteManager.php(162): Codeception\PHPUnit\Runner->doEnhancedRun(Object(Codeception\Suite), Object(PHPUnit_Framework_TestResult), Array)
  #18 /var/www/code/vendor/codeception/codeception/src/Codeception/Codecept.php(183): Codeception\SuiteManager->run(Object(Codeception\PHPUnit\Runner), Object(PHPUnit_Framework_TestResult), Array)
  #19 /var/www/code/vendor/codeception/codeception/src/Codeception/Codecept.php(152): Codeception\Codecept->runSuite(Array, 'acceptance', 'job-orders.feat...')
  #20 /var/www/code/vendor/codeception/codeception/src/Codeception/Command/Run.php(282): Codeception\Codecept->run('acceptance', 'job-orders.feat...')
  #21 /var/www/code/vendor/symfony/symfony/src/Symfony/Component/Console/Command/Command.php(262): Codeception\Command\Run->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
  #22 /var/www/code/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php(826): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
  #23 /var/www/code/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php(189): Symfony\Component\Console\Application->doRunCommand(Object(Codeception\Command\Run), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
  #24 /var/www/code/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php(120): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
  #25 /var/www/code/vendor/codeception/codeception/src/Codeception/Application.php(103): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), NULL)
  #26 /var/www/code/vendor/codeception/codeception/codecept(34): Codeception\Application->run()
  #27 {main}

I'm proposing a small change that will make this problem go away, but I do not know what the right approach is. It seems the logic for limiting the amount of characters displayed on the console is all over the place!!!

My simple "fix":

$allowedLength = floor(($maxLength - $argumentCount + 1) / max($argumentCount, 1));
@edno

This comment has been minimized.

Show comment
Hide comment
@edno

edno Jan 16, 2017

Contributor

Possible fix is to quit the function if $argumentCount equals 0 after line 94 in Step.php.

if ($argumentCount == 0) {
    return '';
}
Contributor

edno commented Jan 16, 2017

Possible fix is to quit the function if $argumentCount equals 0 after line 94 in Step.php.

if ($argumentCount == 0) {
    return '';
}
@DavertMik

This comment has been minimized.

Show comment
Hide comment
@DavertMik

DavertMik Jan 19, 2017

Member

Thanks for investigation. Hopefully it is unrelated to acceptPopup and closePopup, so I will remove that from issue description. Also I have applied a quick fix and test for this case

Member

DavertMik commented Jan 19, 2017

Thanks for investigation. Hopefully it is unrelated to acceptPopup and closePopup, so I will remove that from issue description. Also I have applied a quick fix and test for this case

@DavertMik DavertMik changed the title from WebDriver acceptPopup and cancelPopup are not working in to Division by zero in Step when maxLength < 0 Jan 19, 2017

@mlespiau

This comment has been minimized.

Show comment
Hide comment
@mlespiau

mlespiau Jan 19, 2017

Thanks @DavertMik, do you know when a version with this patch will be available in composer/packagist?

mlespiau commented Jan 19, 2017

Thanks @DavertMik, do you know when a version with this patch will be available in composer/packagist?

@DavertMik

This comment has been minimized.

Show comment
Hide comment
@DavertMik

DavertMik Jan 19, 2017

Member
Member

DavertMik commented Jan 19, 2017

@DavertMik DavertMik closed this in #3931 Jan 19, 2017

DavertMik added a commit that referenced this issue Jan 19, 2017

chris1312 added a commit to chris1312/Codeception that referenced this issue Jun 16, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment