2222
2323final class JsConsoleLogger extends AbstractWebDriverExtension
2424{
25+
2526 /**
2627 * @var array<array|string>
2728 */
@@ -33,35 +34,76 @@ final class JsConsoleLogger extends AbstractWebDriverExtension
3334 Events::STEP_AFTER => 'afterStep ' ,
3435 ];
3536
37+ /**
38+ * Handle event
39+ */
3640 public function afterStep (StepEvent $ event ): void
3741 {
3842 $ this ->checkJsErrors ($ event );
3943 }
4044
45+ /**
46+ * Handle js errors if there are any
47+ *
48+ * @throws \Codeception\Exception\ModuleRequireException
49+ */
4150 private function checkJsErrors (StepEvent $ event ): void
4251 {
4352 $ this ->webDriverModule ->executeInSelenium (function (RemoteWebDriver $ webDriver ) use ($ event ): void {
4453 $ log = $ webDriver ->manage ()->getLog ('browser ' );
4554
46- $ errors = array_values (array_filter ($ log , function ($ entry ): bool {
55+ $ logEntries = array_values (array_filter ($ log , function ($ entry ): bool {
4756 // Permit the error about insecure passwords on non-https
4857 return false === strpos ($ entry ['message ' ], 'non-secure context ' ) &&
4958 false === strpos ($ entry ['message ' ], '/_wdt/ ' );
5059 }));
5160
52- $ errorMsg = count ($ errors ) > 0 ? $ errors [0 ]['message ' ] : '' ;
53-
54- if (count ($ errors ) > 0 ) {
55- $ this ->writeLogFile ($ event , $ log );
61+ if (count ($ logEntries ) === 0 ) {
62+ return ;
5663 }
5764
58- /** @var Asserts $asserts */
65+ // set first entry message as general message
66+ $ errorMsg = count ($ logEntries ) > 0 ? $ logEntries [0 ]['message ' ] : '' ;
67+
68+ // write all entries into log file
69+ $ this ->writeLogFile ($ event , $ log );
5970 $ asserts = $ this ->getModule ('Asserts ' );
60- $ asserts ->assertCount (
61- 0 ,
62- $ errors ,
63- 'Javascript warning: ' . $ errorMsg
64- );
71+
72+ $ groupedErrors = [
73+ 'INFO ' => [],
74+ 'WARNING ' => [],
75+ 'SEVERE ' => []
76+ ];
77+ foreach ($ logEntries as $ entry ) {
78+ $ groupedErrors [$ entry ['level ' ]][] = $ entry ;
79+ }
80+
81+ if (!empty ($ this ->config ['assert_no_warnings ' ])) {
82+ /** @var Asserts $asserts */
83+ $ asserts ->assertCount (
84+ 0 ,
85+ $ groupedErrors ['WARNING ' ],
86+ 'Javascript warning: ' . $ errorMsg
87+ );
88+ }
89+
90+ if (!empty ($ this ->config ['assert_no_errors ' ])) {
91+ /** @var Asserts $asserts */
92+ $ asserts ->assertCount (
93+ 0 ,
94+ $ groupedErrors ['SEVERE ' ],
95+ 'Javascript errors: ' . $ errorMsg
96+ );
97+ }
98+
99+ if (!empty ($ this ->config ['assert_no_console ' ])) {
100+ /** @var Asserts $asserts */
101+ $ asserts ->assertCount (
102+ 0 ,
103+ $ groupedErrors ['INFO ' ],
104+ 'Javascript console entries: ' . $ errorMsg
105+ );
106+ }
65107 });
66108 }
67109
@@ -70,19 +112,24 @@ private function checkJsErrors(StepEvent $event): void
70112 */
71113 private function writeLogFile (StepEvent $ event , array $ log ): void
72114 {
73- file_put_contents ($ this ->getLogFileName ($ event ), print_r ($ log , true ));
115+ // logs need to be appended when test case uses data provider
116+ file_put_contents ($ this ->getLogFileName ($ event ), print_r ($ log , true ), FILE_APPEND );
74117 }
75118
76119 private function getLogFileName (StepEvent $ event ): string
77120 {
78121 return sprintf (
79- '%s/_output/ %s.%s.fail.js-errors.txt ' ,
80- dirname ( __DIR__ ),
122+ '%s/%s.%s.fail.js-errors.txt ' ,
123+ $ this -> getLogDir ( ),
81124 str_replace (['\\' , ': ' ], '. ' , $ this ->getTestName ($ event )),
82125 $ this ->environment
83126 );
84127 }
85128
129+ /**
130+ * @param StepEvent $event
131+ * @return string
132+ */
86133 private function getTestName (StepEvent $ event ): string
87134 {
88135 /** @var SelfDescribing $test */
0 commit comments