mirror of
https://github.com/humhub/humhub.git
synced 2025-01-17 22:28:51 +01:00
Stream Fixes + Tests
This commit is contained in:
parent
1fb8347a69
commit
ac1fe194b9
@ -9,159 +9,140 @@ humhub.initModule('client', function (module, require, $) {
|
||||
/**
|
||||
* Response Wrapper Object for easily accessing common data
|
||||
*/
|
||||
var Response = function (data, dataType) {
|
||||
if(!dataType || dataType === 'json') {
|
||||
$.extend(this, data);
|
||||
} else if(dataType) {
|
||||
this[dataType] = data;
|
||||
} else {
|
||||
this.data = data;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the response is a confirmation of the request
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
Response.prototype.isConfirmation = function () {
|
||||
return this.getStatus() === 0;
|
||||
};
|
||||
|
||||
//TODO: isValidationError status 2
|
||||
|
||||
/**
|
||||
* Checks if the response is marke
|
||||
* @returns {humhub.client_L5.Response.data.status|Boolean}
|
||||
*/
|
||||
Response.prototype.isError = function () {
|
||||
return this.getStatus() > 0 || this.getErrors().length;
|
||||
};
|
||||
|
||||
Response.prototype.getStatus = function () {
|
||||
return (this.status) ? this.status : -1;
|
||||
};
|
||||
|
||||
Response.prototype.getFirstError = function () {
|
||||
var errors = this.getErrors();
|
||||
if (errors.length) {
|
||||
return errors[0];
|
||||
}
|
||||
};
|
||||
|
||||
Response.prototype.setAjaxError = function (xhr, errorThrown, textStatus, data, status) {
|
||||
this.xhr = xhr;
|
||||
var Response = function (xhr, url, textStatus, dataType) {
|
||||
this.url = url;
|
||||
this.status = xhr.status;
|
||||
this.response = xhr.responseJSON || xhr.responseText;
|
||||
//Textstatus = "timeout", "error", "abort", "parsererror", "application"
|
||||
this.textStatus = textStatus;
|
||||
this.status = status || xhr.status;
|
||||
this.errors = [errorThrown];
|
||||
this.dataType = dataType;
|
||||
|
||||
if (!dataType || dataType === 'json') {
|
||||
$.extend(this, this.response);
|
||||
} else if (dataType) {
|
||||
this[dataType] = this.response;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an array of errors or an empty array so getErrors().length is always
|
||||
* safe.
|
||||
* @returns {array} error array or empty array
|
||||
*/
|
||||
Response.prototype.getErrors = function () {
|
||||
var errors = this.errors || [];
|
||||
return (object.isString(errors)) ? [errors] : errors;
|
||||
Response.prototype.setSuccess = function (data) {
|
||||
this.data = data;
|
||||
return this;
|
||||
};
|
||||
|
||||
Response.prototype.toString = function () {
|
||||
return "{ status: " + this.getStatus() + " error: " + this.getErrors() + " textStatus: " + this.textStatus + " }";
|
||||
Response.prototype.setError = function (errorThrown) {
|
||||
this.error = errorThrown;
|
||||
this.validationError = (this.status === 400);
|
||||
return this;
|
||||
};
|
||||
|
||||
Response.prototype.isError = function () {
|
||||
return this.status >= 400;
|
||||
};
|
||||
|
||||
Response.prototype.getLog = function () {
|
||||
var result = $.extend({}, this);
|
||||
|
||||
if(this.response && object.isString(this.response)) {
|
||||
result.response = this.response.substr(0,200)
|
||||
result.response += (this.response.length > 200) ? '...' : '';
|
||||
};
|
||||
|
||||
if(this.html && object.isString(this.html)) {
|
||||
result.html = this.html.substr(0,200)
|
||||
result.html += (this.html.length > 200) ? '...' : '';
|
||||
};
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
var submit = function ($form, cfg, originalEvent) {
|
||||
if($form instanceof $.Event && $form.$form) {
|
||||
if ($form instanceof $.Event && $form.$form) {
|
||||
originalEvent = $form;
|
||||
$form = $form.$form;
|
||||
} else if(cfg instanceof $.Event) {
|
||||
} else if (cfg instanceof $.Event) {
|
||||
originalEvent = cfg;
|
||||
cfg = {};
|
||||
}
|
||||
|
||||
|
||||
cfg = cfg || {};
|
||||
$form = object.isString($form) ? $($form) : $form;
|
||||
cfg.type = $form.attr('method') || 'post';
|
||||
cfg.data = $form.serialize();
|
||||
var url = cfg.url|| $form.attr('action');
|
||||
var url = cfg.url || $form.attr('action');
|
||||
return ajax(url, cfg, originalEvent);
|
||||
};
|
||||
|
||||
var post = function (path, cfg, originalEvent) {
|
||||
if(path instanceof $.Event) {
|
||||
originalEvent = path;
|
||||
path = originalEvent.url;
|
||||
} else if(cfg instanceof $.Event) {
|
||||
var post = function (url, cfg, originalEvent) {
|
||||
if (url instanceof $.Event) {
|
||||
originalEvent = url;
|
||||
url = originalEvent.url;
|
||||
} else if (cfg instanceof $.Event) {
|
||||
originalEvent = cfg;
|
||||
cfg = {};
|
||||
}
|
||||
|
||||
|
||||
cfg = cfg || {};
|
||||
cfg.type = cfg.method = 'POST';
|
||||
return ajax(path, cfg, originalEvent);
|
||||
};
|
||||
|
||||
var get = function (path, cfg, originalEvent) {
|
||||
if(path instanceof $.Event) {
|
||||
originalEvent = path;
|
||||
path = originalEvent.url;
|
||||
} else if(cfg instanceof $.Event) {
|
||||
originalEvent = cfg;
|
||||
cfg = {};
|
||||
}
|
||||
|
||||
cfg = cfg || {};
|
||||
cfg.type = cfg.method = 'GET';
|
||||
return ajax(path, cfg, originalEvent);
|
||||
return ajax(url, cfg, originalEvent);
|
||||
};
|
||||
|
||||
var ajax = function (path, cfg, originalEvent) {
|
||||
|
||||
// support for ajax(path, event) and ajax(path, successhandler);
|
||||
if(cfg instanceof $.Event) {
|
||||
var get = function (url, cfg, originalEvent) {
|
||||
if (url instanceof $.Event) {
|
||||
originalEvent = url;
|
||||
url = originalEvent.url;
|
||||
} else if (cfg instanceof $.Event) {
|
||||
originalEvent = cfg;
|
||||
cfg = {};
|
||||
} else if(object.isFunction(cfg)) {
|
||||
cfg = {'success' : cfg};
|
||||
}
|
||||
|
||||
cfg = cfg || {};
|
||||
cfg.type = cfg.method = 'GET';
|
||||
return ajax(url, cfg, originalEvent);
|
||||
};
|
||||
|
||||
var ajax = function (url, cfg, originalEvent) {
|
||||
|
||||
// support for ajax(url, event) and ajax(path, successhandler);
|
||||
if (cfg instanceof $.Event) {
|
||||
originalEvent = cfg;
|
||||
cfg = {};
|
||||
} else if (object.isFunction(cfg)) {
|
||||
cfg = {'success': cfg};
|
||||
}
|
||||
|
||||
|
||||
var promise = new Promise(function (resolve, reject) {
|
||||
cfg = cfg || {};
|
||||
|
||||
//Wrap the actual error handler with our own and call
|
||||
|
||||
var errorHandler = cfg.error;
|
||||
var error = function (xhr, textStatus, errorThrown, data) {
|
||||
//Textstatus = "timeout", "error", "abort", "parsererror", "application"
|
||||
var error = function (xhr, textStatus, errorThrown) {
|
||||
var response = new Response(xhr, url, textStatus, cfg.dataType).setError(errorThrown);
|
||||
|
||||
if (errorHandler && object.isFunction(errorHandler)) {
|
||||
var response = new Response();
|
||||
response.setAjaxError(xhr, errorThrown, textStatus, data, xhr.status);
|
||||
errorHandler(response);
|
||||
}
|
||||
|
||||
|
||||
finish(originalEvent);
|
||||
reject({'url' : path, 'textStatus': textStatus, 'response': xhr.responseJSON, 'error': errorThrown, 'data': data, 'status': xhr.status});
|
||||
reject(response);
|
||||
};
|
||||
|
||||
var successHandler = cfg.success;
|
||||
var success = function (data, textStatus, xhr) {
|
||||
var response = new Response(data, cfg.dataType);
|
||||
if (response.isError()) { //Application errors
|
||||
return error(xhr, "application", response.getErrors(), data, response.getStatus());
|
||||
} else if (successHandler) {
|
||||
response.textStatus = textStatus;
|
||||
response.xhr = xhr;
|
||||
var response = new Response(xhr, url, textStatus, cfg.dataType).setSuccess(data);
|
||||
if (successHandler) {
|
||||
successHandler(response);
|
||||
}
|
||||
|
||||
|
||||
finish(originalEvent);
|
||||
resolve(response);
|
||||
|
||||
|
||||
// Other modules can register global handler by the response type given by the backend.
|
||||
// For example {type:'modal', 'content': '...')
|
||||
if(response.type) {
|
||||
event.trigger('humhub:modules:client:response:'+response.type);
|
||||
if (response.type) {
|
||||
event.trigger('humhub:modules:client:response:' + response.type);
|
||||
}
|
||||
|
||||
promise.done(function() {
|
||||
|
||||
promise.done(function () {
|
||||
// If content with <link> tags are inserted in resolve, the ajaxComplete handler in yii.js
|
||||
// makes sure redundant stylesheets are removed. Here we get sure it is called after inserting the response.
|
||||
$(document).trigger('ajaxComplete');
|
||||
@ -171,28 +152,55 @@ humhub.initModule('client', function (module, require, $) {
|
||||
//Overwriting the handler with our wrapper handler
|
||||
cfg.success = success;
|
||||
cfg.error = error;
|
||||
cfg.url = path;
|
||||
cfg.url = url;
|
||||
|
||||
//Setting some default values
|
||||
cfg.dataType = cfg.dataType || "json";
|
||||
|
||||
$.ajax(cfg);
|
||||
});
|
||||
|
||||
|
||||
promise.status = function (setting) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
promise.then(function (response) {
|
||||
try {
|
||||
if (setting[response.status]) {
|
||||
setting[response.status](response);
|
||||
}
|
||||
resolve(response);
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
}).catch(function (response) {
|
||||
try {
|
||||
if (setting[response.status]) {
|
||||
setting[response.status](response);
|
||||
resolve(response);
|
||||
} else {
|
||||
reject(response);
|
||||
}
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
var finish = function(originalEvent) {
|
||||
if(originalEvent && object.isFunction(originalEvent.finish)) {
|
||||
|
||||
var finish = function (originalEvent) {
|
||||
if (originalEvent && object.isFunction(originalEvent.finish)) {
|
||||
originalEvent.finish();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
module.export({
|
||||
ajax: ajax,
|
||||
post: post,
|
||||
get: get,
|
||||
submit: submit
|
||||
submit: submit,
|
||||
Response: Response
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -8,6 +8,7 @@ humhub.initModule('ui.status', function (module, require, $) {
|
||||
var event = require('event');
|
||||
var log = require('log');
|
||||
var object = require('util').object;
|
||||
var client = require('client');
|
||||
|
||||
var SELECTOR_ROOT = '#status-bar';
|
||||
var SELECTOR_BODY = '.status-bar-body';
|
||||
@ -113,9 +114,12 @@ humhub.initModule('ui.status', function (module, require, $) {
|
||||
if (error.error instanceof Error) {
|
||||
error.stack = (error.error.stack) ? error.error.stack : undefined;
|
||||
error.error = error.error.message;
|
||||
} else if(error instanceof client.Response) {
|
||||
error = error.getLog();
|
||||
}
|
||||
try {
|
||||
return JSON.stringify(error, null, 4);
|
||||
// encode
|
||||
return $('<div/>').text(JSON.stringify(error, null, 4)).html();
|
||||
} catch(e) {
|
||||
return error.toString();
|
||||
}
|
||||
|
@ -44,6 +44,20 @@ humhub.initModule('util', function(module, require, $) {
|
||||
inherits: function(Sub, Parent) {
|
||||
Sub.prototype = Object.create(Parent.prototype);
|
||||
Sub._super = Parent.prototype;
|
||||
Sub.prototype.super = function(method) {
|
||||
if(!Sub._super[arguments[0]]) {
|
||||
throw new Error('Call of undefined method of super type');
|
||||
}
|
||||
|
||||
var args;
|
||||
|
||||
if(arguments.length > 1){
|
||||
args = [];
|
||||
Array.prototype.push.apply( args, arguments );
|
||||
args.shift();
|
||||
}
|
||||
return Sub._super[arguments[0]].apply(this, args);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -47,13 +47,13 @@ class CoreApiAsset extends AssetBundle
|
||||
'js/humhub/humhub.util.js',
|
||||
'js/humhub/humhub.log.js',
|
||||
//'js/humhub/humhub.scripts.js',
|
||||
'js/humhub/humhub.ui.status.js',
|
||||
'js/humhub/humhub.ui.additions.js',
|
||||
'js/humhub/humhub.ui.loader.js',
|
||||
'js/humhub/humhub.ui.modal.js',
|
||||
'js/humhub/humhub.client.js',
|
||||
'js/humhub/humhub.client.pjax.js',
|
||||
'js/humhub/humhub.action.js'
|
||||
'js/humhub/humhub.action.js',
|
||||
'js/humhub/humhub.ui.status.js'
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -85,7 +85,7 @@ humhub.initModule('activity', function (module, require, $) {
|
||||
var stream = getStream();
|
||||
|
||||
if (!stream) {
|
||||
console.log('No activity stream found!');
|
||||
module.log.info('No activity stream found!');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -96,16 +96,16 @@ humhub.initModule('activity', function (module, require, $) {
|
||||
// listen for scrolling event yes or no
|
||||
var scrolling = true;
|
||||
|
||||
stream.$content.scroll(function () {
|
||||
|
||||
stream.$content.scroll(function (evt) {
|
||||
|
||||
// save height of the overflow container
|
||||
var _containerHeight = $("#activityContents").height();
|
||||
var _containerHeight = stream.$content.height();
|
||||
|
||||
// save scroll height
|
||||
var _scrollHeight = $("#activityContents").prop("scrollHeight");
|
||||
var _scrollHeight = stream.$content.prop("scrollHeight");
|
||||
|
||||
// save current scrollbar position
|
||||
var _currentScrollPosition = $('#activityContents').scrollTop();
|
||||
var _currentScrollPosition = stream.$content.scrollTop();
|
||||
|
||||
// load more activites if current scroll position is near scroll height
|
||||
if (_currentScrollPosition >= (_scrollHeight - _containerHeight - 30)) {
|
||||
|
@ -31,6 +31,7 @@ $this->registerJsVar('activityInfoUrl', $infoUrl);
|
||||
cursorborder: "",
|
||||
cursorcolor: "#555",
|
||||
cursoropacitymax: "0.2",
|
||||
nativeparentscrolling: false,
|
||||
railpadding: {top: 0, right: 3, left: 0, bottom: 0}
|
||||
});
|
||||
|
||||
|
24
protected/humhub/modules/comment/tests/codeception.yml
Normal file
24
protected/humhub/modules/comment/tests/codeception.yml
Normal file
@ -0,0 +1,24 @@
|
||||
actor: Tester
|
||||
namespace: comment
|
||||
settings:
|
||||
bootstrap: _bootstrap.php
|
||||
suite_class: \PHPUnit_Framework_TestSuite
|
||||
colors: true
|
||||
shuffle: false
|
||||
memory_limit: 1024M
|
||||
log: true
|
||||
|
||||
# This value controls whether PHPUnit attempts to backup global variables
|
||||
# See https://phpunit.de/manual/current/en/appendixes.annotations.html#appendixes.annotations.backupGlobals
|
||||
backup_globals: true
|
||||
paths:
|
||||
tests: codeception
|
||||
log: codeception/_output
|
||||
data: codeception/_data
|
||||
helpers: codeception/_support
|
||||
envs: config/env
|
||||
config:
|
||||
# the entry script URL (with host info) for functional and acceptance tests
|
||||
# PLEASE ADJUST IT TO THE ACTUAL ENTRY SCRIPT URL
|
||||
test_entry_url: http://localhost:8080/index-test.php
|
||||
|
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/**
|
||||
* This is the initial test bootstrap, which will load the default test bootstrap from the humhub core
|
||||
*/
|
||||
// Parse the environment arguments (Note: only simple --env ENV is supported no comma sepration merge...)
|
||||
$argv = $_SERVER['argv'];
|
||||
$env = [];
|
||||
for ($i = 0; $i < count($argv); $i++) {
|
||||
if ($argv[$i] === '--env') {
|
||||
$env[] = explode(',', $argv[++$i]);
|
||||
}
|
||||
}
|
||||
|
||||
// If environment was set try loading special environment config else load default
|
||||
if (count($env) > 0) {
|
||||
\Codeception\Configuration::append(['environment' => $env]);
|
||||
|
||||
echo 'Run execution environment: ' . $env[0][0] . PHP_EOL;
|
||||
|
||||
$envCfgFile = dirname(__DIR__) . '/config/env/test.' . $env[0][0] . '.php';
|
||||
|
||||
if (file_exists($envCfgFile)) {
|
||||
$cfg = array_merge(require_once(__DIR__ . '/../config/test.php'), require_once($envCfgFile));
|
||||
}
|
||||
}
|
||||
|
||||
// If no environment is set we have to load the default config
|
||||
if (!isset($cfg)) {
|
||||
$cfg = require_once(__DIR__ . '/../config/test.php');
|
||||
}
|
||||
|
||||
// If no humhub_root is given we assume our module is in the a root to be in /protected/humhub/modules/<module>/tests/codeception directory
|
||||
$cfg['humhub_root'] = isset($cfg['humhub_root']) ? $cfg['humhub_root'] : dirname(__DIR__) . '/../../../../..';
|
||||
|
||||
echo 'Using HumHub Root: ' . $cfg['humhub_root'] . PHP_EOL;
|
||||
|
||||
// Load default test bootstrap
|
||||
require_once($cfg['humhub_root'] . '/protected/humhub/tests/codeception/_bootstrap.php');
|
||||
|
||||
// Overwrite the default test alias
|
||||
Yii::setAlias('@tests', dirname(__DIR__));
|
||||
Yii::setAlias('@env', '@tests/config/env');
|
||||
Yii::setAlias('@root', $cfg['humhub_root']);
|
||||
Yii::setAlias('@humhubTests', $cfg['humhub_root'] . '/protected/humhub/tests');
|
||||
|
||||
// Load all supporting test classes needed for test execution
|
||||
\Codeception\Util\Autoload::addNamespace('', Yii::getAlias('@humhubTests/codeception/_support'));
|
||||
\Codeception\Util\Autoload::addNamespace('tests\codeception\fixtures', Yii::getAlias('@humhubTests/codeception/fixtures'));
|
||||
\Codeception\Util\Autoload::addNamespace('', Yii::getAlias('@humhubTests/codeception/_pages'));
|
||||
if(isset($cfg['modules'])) {
|
||||
\Codeception\Configuration::append(['humhub_modules' => $cfg['modules']]);
|
||||
}
|
||||
|
||||
if(isset($cfg['fixtures'])) {
|
||||
\Codeception\Configuration::append(['fixtures' => $cfg['fixtures']]);
|
||||
}
|
||||
?>
|
4
protected/humhub/modules/comment/tests/codeception/_output/.gitignore
vendored
Normal file
4
protected/humhub/modules/comment/tests/codeception/_output/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
# Ignore everything in this directory
|
||||
*
|
||||
# Except this file
|
||||
!.gitignore
|
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
namespace comment;
|
||||
|
||||
/**
|
||||
* Inherited Methods
|
||||
* @method void wantToTest($text)
|
||||
* @method void wantTo($text)
|
||||
* @method void execute($callable)
|
||||
* @method void expectTo($prediction)
|
||||
* @method void expect($prediction)
|
||||
* @method void amGoingTo($argumentation)
|
||||
* @method void am($role)
|
||||
* @method void lookForwardTo($achieveValue)
|
||||
* @method void comment($description)
|
||||
* @method \Codeception\Lib\Friend haveFriend($name, $actorClass = null)
|
||||
*
|
||||
* @SuppressWarnings(PHPMD)
|
||||
*/
|
||||
class AcceptanceTester extends \AcceptanceTester
|
||||
{
|
||||
use _generated\AcceptanceTesterActions;
|
||||
|
||||
/**
|
||||
* Define custom actions here
|
||||
*/
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
namespace comment;
|
||||
|
||||
/**
|
||||
* Inherited Methods
|
||||
* @method void wantToTest($text)
|
||||
* @method void wantTo($text)
|
||||
* @method void execute($callable)
|
||||
* @method void expectTo($prediction)
|
||||
* @method void expect($prediction)
|
||||
* @method void amGoingTo($argumentation)
|
||||
* @method void am($role)
|
||||
* @method void lookForwardTo($achieveValue)
|
||||
* @method void comment($description)
|
||||
* @method \Codeception\Lib\Friend haveFriend($name, $actorClass = null)
|
||||
*
|
||||
* @SuppressWarnings(PHPMD)
|
||||
*/
|
||||
class FunctionalTester extends \FunctionalTester
|
||||
{
|
||||
use _generated\FunctionalTesterActions;
|
||||
|
||||
/**
|
||||
* Define custom actions here
|
||||
*/
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
namespace comment;
|
||||
|
||||
/**
|
||||
* Inherited Methods
|
||||
* @method void wantToTest($text)
|
||||
* @method void wantTo($text)
|
||||
* @method void execute($callable)
|
||||
* @method void expectTo($prediction)
|
||||
* @method void expect($prediction)
|
||||
* @method void amGoingTo($argumentation)
|
||||
* @method void am($role)
|
||||
* @method void lookForwardTo($achieveValue)
|
||||
* @method void comment($description)
|
||||
* @method \Codeception\Lib\Friend haveFriend($name, $actorClass = null)
|
||||
*
|
||||
* @SuppressWarnings(PHPMD)
|
||||
*/
|
||||
class UnitTester extends \UnitTester
|
||||
{
|
||||
use _generated\UnitTesterActions;
|
||||
|
||||
/**
|
||||
* Define custom actions here
|
||||
*/
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,38 @@
|
||||
<?php //[STAMP] 0468b7e2480518455b63a22d3aa6f7c2
|
||||
namespace stream\_generated;
|
||||
|
||||
// This class was automatically generated by build task
|
||||
// You should not change it manually as it will be overwritten on next build
|
||||
// @codingStandardsIgnoreFile
|
||||
|
||||
use tests\codeception\_support\CodeHelper;
|
||||
|
||||
trait UnitTesterActions
|
||||
{
|
||||
/**
|
||||
* @return \Codeception\Scenario
|
||||
*/
|
||||
abstract protected function getScenario();
|
||||
|
||||
|
||||
/**
|
||||
* [!] Method is generated. Documentation taken from corresponding module.
|
||||
*
|
||||
*
|
||||
* @see \tests\codeception\_support\CodeHelper::assertContainsError()
|
||||
*/
|
||||
public function assertContainsError($model, $message) {
|
||||
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertContainsError', func_get_args()));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* [!] Method is generated. Documentation taken from corresponding module.
|
||||
*
|
||||
*
|
||||
* @see \tests\codeception\_support\CodeHelper::assertNotContainsError()
|
||||
*/
|
||||
public function assertNotContainsError($model, $message) {
|
||||
return $this->getScenario()->runStep(new \Codeception\Step\Action('assertNotContainsError', func_get_args()));
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
# Codeception Test Suite Configuration
|
||||
|
||||
# suite for acceptance tests.
|
||||
# perform tests in browser using the Selenium-like tools.
|
||||
# powered by Mink (http://mink.behat.org).
|
||||
# (tip: that's what your customer will see).
|
||||
# (tip: test your ajax and javascript by one of Mink drivers).
|
||||
|
||||
# RUN `build` COMMAND AFTER ADDING/REMOVING MODULES.
|
||||
|
||||
class_name: AcceptanceTester
|
||||
modules:
|
||||
enabled:
|
||||
- WebDriver
|
||||
- tests\codeception\_support\WebHelper
|
||||
- tests\codeception\_support\DynamicFixtureHelper
|
||||
config:
|
||||
WebDriver:
|
||||
url: http://localhost:8080/
|
||||
browser: phantomjs
|
||||
window_size: 1024x768
|
||||
lang: en
|
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Initialize the HumHub Application for functional testing. The default application configuration for this suite can be overwritten
|
||||
* in @tests/config/functional.php
|
||||
*/
|
||||
require(Yii::getAlias('@humhubTests/codeception/acceptance/_bootstrap.php'));
|
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
return \tests\codeception\_support\HumHubTestConfiguration::getSuiteConfig('functional');
|
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
return \tests\codeception\_support\HumHubTestConfiguration::getSuiteConfig('unit');
|
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @link https://www.humhub.org/
|
||||
* @copyright Copyright (c) 2015 HumHub GmbH & Co. KG
|
||||
* @license https://www.humhub.com/licences
|
||||
*/
|
||||
|
||||
namespace humhub\modules\comment\tests\codeception\fixtures;
|
||||
|
||||
use yii\test\ActiveFixture;
|
||||
|
||||
class CommentFixture extends ActiveFixture
|
||||
{
|
||||
|
||||
public $modelClass = 'humhub\modules\comment\models\Comment';
|
||||
public $dataFile = '@modules/comment/tests/codeception/fixtures/data/comment.php';
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
return [];
|
@ -0,0 +1,18 @@
|
||||
# Codeception Test Suite Configuration
|
||||
|
||||
# suite for functional (integration) tests.
|
||||
# emulate web requests and make application process them.
|
||||
# (tip: better to use with frameworks).
|
||||
|
||||
# RUN `build` COMMAND AFTER ADDING/REMOVING MODULES.
|
||||
class_name: FunctionalTester
|
||||
modules:
|
||||
enabled:
|
||||
- Filesystem
|
||||
- Yii2
|
||||
- tests\codeception\_support\TestHelper
|
||||
- tests\codeception\_support\DynamicFixtureHelper
|
||||
- tests\codeception\_support\HumHubHelper
|
||||
config:
|
||||
Yii2:
|
||||
configFile: 'codeception/config/functional.php'
|
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Initialize the HumHub Application for functional testing. The default application configuration for this suite can be overwritten
|
||||
* in @tests/config/functional.php
|
||||
*/
|
||||
require(Yii::getAlias('@humhubTests/codeception/functional/_bootstrap.php'));
|
@ -0,0 +1,9 @@
|
||||
# Codeception Test Suite Configuration
|
||||
|
||||
# suite for unit (internal) tests.
|
||||
# RUN `build` COMMAND AFTER ADDING/REMOVING MODULES.
|
||||
|
||||
class_name: UnitTester
|
||||
modules:
|
||||
enabled:
|
||||
- tests\codeception\_support\CodeHelper
|
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Initialize the HumHub Application for functional testing. The default application configuration for this suite can be overwritten
|
||||
* in @tests/config/functional.php
|
||||
*/
|
||||
require(Yii::getAlias('@humhubTests/codeception/unit/_bootstrap.php'));
|
5
protected/humhub/modules/comment/tests/config/common.php
Normal file
5
protected/humhub/modules/comment/tests/config/common.php
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
/**
|
||||
* This config is shared by all suites (unit/functional/acceptance) and can be overwritten by a suite config (e.g. functional.php)
|
||||
*/
|
||||
return [];
|
4
protected/humhub/modules/comment/tests/config/env/.gitignore
vendored
Normal file
4
protected/humhub/modules/comment/tests/config/env/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
# Ignore everything in this directory
|
||||
*
|
||||
# Except this file
|
||||
!.gitignore
|
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
/**
|
||||
* Here you can overwrite the default config for the functional suite. The default config resides in @humhubTests/codeception/config/config.php
|
||||
*/
|
||||
return [];
|
11
protected/humhub/modules/comment/tests/config/test.php
Normal file
11
protected/humhub/modules/comment/tests/config/test.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'fixtures' => [
|
||||
'default',
|
||||
'content' => 'humhub\modules\content\tests\codeception\fixtures\ContentFixture',
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
|
5
protected/humhub/modules/comment/tests/config/unit.php
Normal file
5
protected/humhub/modules/comment/tests/config/unit.php
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
/**
|
||||
* Here you can overwrite your functional humhub config. The default config resiedes in @humhubTests/codeception/config/config.php
|
||||
*/
|
||||
return [];
|
@ -18,7 +18,8 @@ class ContentFixture extends ActiveFixture
|
||||
|
||||
public $depends = [
|
||||
'humhub\modules\content\tests\codeception\fixtures\ContentContainerFixture',
|
||||
'humhub\modules\post\tests\codeception\fixtures\PostFixture'
|
||||
'humhub\modules\post\tests\codeception\fixtures\PostFixture',
|
||||
'humhub\modules\comment\tests\codeception\fixtures\CommentFixture'
|
||||
];
|
||||
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ use humhub\compat\CActiveForm;
|
||||
|
||||
|
||||
?>
|
||||
<div class="content_edit" id="post_edit_<?php echo $post->id; ?>">
|
||||
<div class="content content_edit" id="post_edit_<?php echo $post->id; ?>">
|
||||
<?php $form = CActiveForm::begin(['id' => 'post-edit-form_' . $post->id]); ?>
|
||||
|
||||
<!-- create contenteditable div for HEditorWidget to place the data -->
|
||||
|
@ -75,6 +75,8 @@ humhub.initModule('stream', function (module, require, $) {
|
||||
*/
|
||||
var StreamEntry = function (id) {
|
||||
Content.call(this, id);
|
||||
// Set the stream so we have it even if the entry is detached.
|
||||
this.stream();
|
||||
};
|
||||
|
||||
object.inherits(StreamEntry, Content);
|
||||
@ -84,21 +86,23 @@ humhub.initModule('stream', function (module, require, $) {
|
||||
};
|
||||
|
||||
StreamEntry.prototype.delete = function () {
|
||||
// Search for a nestet content component or call default content delete
|
||||
var content = this.getContentComponent();
|
||||
var promise = (content && content.delete) ? content.delete()
|
||||
: StreamEntry._super.delete.call(this);
|
||||
// Either call delete of a nestet content component or call default content delete
|
||||
var content = this.contentComponent();
|
||||
var promise = (content && content.delete) ? content.delete() : this.super('delete');
|
||||
|
||||
var stream = this.stream();
|
||||
promise.then(function ($confirm) {
|
||||
if ($confirm) {
|
||||
module.log.success('success.delete');
|
||||
}
|
||||
}).catch(function (err) {
|
||||
module.log.error(err, true);
|
||||
}).finally(function () {
|
||||
stream.onChange();
|
||||
});
|
||||
};
|
||||
|
||||
StreamEntry.prototype.getContentComponent = function () {
|
||||
StreamEntry.prototype.contentComponent = function () {
|
||||
var children = this.children();
|
||||
return children.length ? children[0] : undefined;
|
||||
};
|
||||
@ -121,6 +125,12 @@ humhub.initModule('stream', function (module, require, $) {
|
||||
StreamEntry.prototype.edit = function (evt) {
|
||||
var that = this;
|
||||
|
||||
if (this.$.data('lastEdit')) {
|
||||
that.replaceContent(this.$.data('lastEdit'));
|
||||
that.$.find('input[type="text"], textarea, [contenteditable="true"]').first().focus();
|
||||
return;
|
||||
}
|
||||
|
||||
client.get(evt, {
|
||||
dataType: 'html',
|
||||
beforeSend: function () {
|
||||
@ -136,14 +146,15 @@ humhub.initModule('stream', function (module, require, $) {
|
||||
});
|
||||
|
||||
// Listen to click events outside of the stream entry and cancel edit.
|
||||
$('body').off('click.humhub:modules:stream:edit').on('click.humhub:modules:stream:edit', function (e) {
|
||||
$('body').off('mousedown.humhub:modules:stream:edit').one('mousedown.humhub:modules:stream:edit', function (e) {
|
||||
if (!$(e.target).closest('[data-content-key="' + that.getKey() + '"]').length) {
|
||||
var $editContent = that.$.find('.content_edit:first');
|
||||
that.$.data('lastEdit', $editContent.clone(true));
|
||||
if ($editContent && that.$.data('oldContent')) {
|
||||
$editContent.replaceWith(that.$.data('oldContent'));
|
||||
that.$.data('oldContent', undefined);
|
||||
}
|
||||
$('body').off('click.humhub:modules:stream:edit');
|
||||
$('body').off('mousedown.humhub:modules:stream:edit');
|
||||
}
|
||||
});
|
||||
};
|
||||
@ -162,12 +173,20 @@ humhub.initModule('stream', function (module, require, $) {
|
||||
beforeSend: function () {
|
||||
that.loader();
|
||||
}
|
||||
}).then(function (response) {
|
||||
that.$.html(response.html);
|
||||
module.log.success('success.edit');
|
||||
that.highlight();
|
||||
}).status({
|
||||
200: function (response) {
|
||||
that.$.html(response.html);
|
||||
module.log.success('success.edit');
|
||||
that.highlight();
|
||||
},
|
||||
400: function (response) {
|
||||
that.replaceContent(response.html);
|
||||
}
|
||||
}).catch(function (e) {
|
||||
module.log.error(e, true);
|
||||
}).finally(function () {
|
||||
$('body').off('mousedown.humhub:modules:stream:edit');
|
||||
that.$.data('lastEdit', undefined);
|
||||
that.loader(false);
|
||||
});
|
||||
};
|
||||
@ -188,7 +207,7 @@ humhub.initModule('stream', function (module, require, $) {
|
||||
};
|
||||
|
||||
StreamEntry.prototype.getContent = function () {
|
||||
return this.$.find('.content:first');
|
||||
return this.$.find('.content, .content_edit').first();
|
||||
};
|
||||
|
||||
StreamEntry.prototype.highlight = function () {
|
||||
@ -263,7 +282,7 @@ humhub.initModule('stream', function (module, require, $) {
|
||||
} else {
|
||||
that.remove().then(function () {
|
||||
module.log.success('success.archive', true);
|
||||
})
|
||||
});
|
||||
}
|
||||
} else {
|
||||
module.log.error(response, true);
|
||||
@ -274,6 +293,12 @@ humhub.initModule('stream', function (module, require, $) {
|
||||
});
|
||||
};
|
||||
|
||||
StreamEntry.prototype.remove = function () {
|
||||
var stream = this.stream();
|
||||
return this.super('remove')
|
||||
.then($.proxy(stream.onChange, stream));
|
||||
};
|
||||
|
||||
StreamEntry.prototype.unarchive = function (evt) {
|
||||
var that = this;
|
||||
this.loader();
|
||||
@ -291,7 +316,11 @@ humhub.initModule('stream', function (module, require, $) {
|
||||
|
||||
StreamEntry.prototype.stream = function () {
|
||||
// Just return the parent stream component.
|
||||
return this.parent();
|
||||
if(!this.$.data('stream')) {
|
||||
return this.$.data('stream', this.parent());
|
||||
}
|
||||
|
||||
return this.$.data('stream');
|
||||
};
|
||||
|
||||
/**
|
||||
@ -553,12 +582,14 @@ humhub.initModule('stream', function (module, require, $) {
|
||||
var $html = $(html).hide();
|
||||
this.$content.prepend($html);
|
||||
$html.fadeIn();
|
||||
this.onChange();
|
||||
};
|
||||
|
||||
Stream.prototype.appendEntry = function (html) {
|
||||
var $html = $(html).hide();
|
||||
this.$content.append($html);
|
||||
$html.fadeIn();
|
||||
this.onChange();
|
||||
};
|
||||
|
||||
|
||||
|
4
protected/humhub/modules/stream/tests/codeception/_output/.gitignore
vendored
Normal file
4
protected/humhub/modules/stream/tests/codeception/_output/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
# Ignore everything in this directory
|
||||
*
|
||||
# Except this file
|
||||
!.gitignore
|
@ -42,9 +42,7 @@ class StreamCest
|
||||
$I->wantToTest('the archivation of a stream entry');
|
||||
$I->amGoingTo('create a new post and archive it afterwards');
|
||||
|
||||
$I->click('#contentForm_message_contenteditable');
|
||||
$I->fillField('#contentForm_message_contenteditable', 'This is my stream test post!');
|
||||
$I->click('#post_submit_button');
|
||||
$I->createPost('This is my stream test post!');
|
||||
|
||||
$newEntrySelector = '[data-content-key="12"]';
|
||||
|
||||
@ -62,7 +60,7 @@ class StreamCest
|
||||
$I->dontSeeElement($newEntrySelector);
|
||||
|
||||
$I->amGoingTo('check if my post is visible with filter include archived');
|
||||
$I->click('#filter .dropdown-toggle');
|
||||
$I->click('Filter', '#filter');
|
||||
$I->waitForElementVisible('#filter_entry_archived');
|
||||
$I->click('#filter_entry_archived');
|
||||
|
||||
@ -95,12 +93,10 @@ class StreamCest
|
||||
{
|
||||
$I->amUser();
|
||||
$I->amOnSpace2();
|
||||
$I->wantToTest('the deletion of a stream entry');
|
||||
$I->wantToTest('the stick of posts');
|
||||
$I->amGoingTo('create a new post and delete it afterwards');
|
||||
|
||||
$I->click('#contentForm_message_contenteditable');
|
||||
$I->fillField('#contentForm_message_contenteditable', 'This is my first stream test post!');
|
||||
$I->click('#post_submit_button');
|
||||
$I->createPost('This is my first stream test post!');
|
||||
|
||||
$newEntrySelector = '[data-content-key="12"]';
|
||||
|
||||
@ -108,9 +104,8 @@ class StreamCest
|
||||
$I->see('This is my first stream test post', '.wall-entry');
|
||||
|
||||
$I->amGoingTo('create another post');
|
||||
$I->click('#contentForm_message_contenteditable');
|
||||
$I->fillField('#contentForm_message_contenteditable', 'This is my second stream test post!');
|
||||
$I->click('#post_submit_button');
|
||||
|
||||
$I->createPost('This is my second stream test post!');
|
||||
|
||||
$newEntrySelector2 = '[data-content-key="14"]';
|
||||
$I->waitForElementVisible($newEntrySelector2);
|
||||
@ -139,33 +134,104 @@ class StreamCest
|
||||
{
|
||||
$I->amUser();
|
||||
$I->amOnSpace2();
|
||||
$I->wantToTest('the deletion of a stream entry');
|
||||
$I->wantToTest('the edit post mechanism');
|
||||
$I->amGoingTo('create a new post and delete it afterwards');
|
||||
|
||||
$I->click('#contentForm_message_contenteditable');
|
||||
$I->fillField('#contentForm_message_contenteditable', 'This is my first stream test post!');
|
||||
$I->click('#post_submit_button');
|
||||
$I->createPost('This is my first stream test post!');
|
||||
|
||||
$newEntrySelector = '[data-content-key="12"]';
|
||||
|
||||
$I->waitForElementVisible($newEntrySelector);
|
||||
$I->see('This is my first stream test post', '.wall-entry');
|
||||
|
||||
|
||||
$I->amGoingTo('edit my new post');
|
||||
$I->click('.preferences', $newEntrySelector);
|
||||
$I->waitForText('Edit', 10);
|
||||
$I->click('Edit', $newEntrySelector);
|
||||
|
||||
$I->waitForElementVisible($newEntrySelector.' .content_edit', 20);
|
||||
$I->fillField($newEntrySelector.' [contenteditable]', 'This is my edited post!');
|
||||
$I->click('Save', $newEntrySelector);;
|
||||
|
||||
|
||||
$I->waitForElementVisible($newEntrySelector . ' .content_edit', 20);
|
||||
$I->fillField($newEntrySelector . ' [contenteditable]', 'This is my edited post!');
|
||||
$I->click('Save', $newEntrySelector);
|
||||
;
|
||||
|
||||
$I->seeSuccess('Saved');
|
||||
$I->seeElement($newEntrySelector);
|
||||
$I->see('This is my edited post!', $newEntrySelector);
|
||||
}
|
||||
|
||||
public function testEmptyStream(AcceptanceTester $I)
|
||||
{
|
||||
$I->amUser();
|
||||
$I->amOnSpace3();
|
||||
$I->wantToTest('the empty stream message and filter');
|
||||
|
||||
$I->waitForText('This space is still empty!');
|
||||
$I->dontSeeElement('#filter');
|
||||
|
||||
$I->amGoingTo('create a new post and delete it afterwards');
|
||||
|
||||
$I->createPost('This is my first stream test post!');
|
||||
|
||||
$I->wait(1);
|
||||
|
||||
$I->amGoingTo('Delete my new post again.');
|
||||
$I->dontSee('This space is still empty!');
|
||||
$I->seeElement('#filter');
|
||||
$I->click('.preferences', '[data-stream-entry]:nth-of-type(1)');
|
||||
$I->wait(1);
|
||||
$I->click('Delete');
|
||||
|
||||
$I->waitForElementVisible('#globalModalConfirm', 5);
|
||||
$I->see('Do you really want to perform this action?');
|
||||
$I->click('Confirm');
|
||||
|
||||
$I->seeSuccess('The content has been deleted');
|
||||
$I->see('This space is still empty!');
|
||||
$I->dontSeeElement('#filter');
|
||||
}
|
||||
|
||||
public function testSortStream(AcceptanceTester $I)
|
||||
{
|
||||
$I->amUser();
|
||||
$I->amOnSpace3();
|
||||
$I->wantToTest('the stream entry ordering');
|
||||
$I->amGoingTo('create a new post and delete it afterwards');
|
||||
|
||||
$I->createPost('POST1');
|
||||
$I->createPost('POST2');
|
||||
$I->createPost('POST3');
|
||||
$I->createPost('POST4');
|
||||
$I->createPost('POST5');
|
||||
|
||||
$I->see('POST5', '.s2_streamContent > [data-stream-entry]:nth-of-type(1)');
|
||||
$I->see('POST4', '.s2_streamContent > [data-stream-entry]:nth-of-type(2)');
|
||||
$I->see('POST3', '.s2_streamContent > [data-stream-entry]:nth-of-type(3)');
|
||||
$I->see('POST2', '.s2_streamContent > [data-stream-entry]:nth-of-type(4)');
|
||||
$I->see('POST1', '.s2_streamContent > [data-stream-entry]:nth-of-type(5)');
|
||||
|
||||
$post4Selector = '[data-stream-entry][data-content-key="18"]';
|
||||
|
||||
$I->click('Comment', $post4Selector);
|
||||
$I->fillField($post4Selector . ' [contenteditable]', 'My Comment!');
|
||||
$I->click('Send', $post4Selector . ' .comment-buttons');
|
||||
|
||||
$I->scrollTop();
|
||||
|
||||
$I->click('.stream-sorting', '#filter');
|
||||
$I->waitForElementVisible('#sorting_u');
|
||||
$I->click('#sorting_u');
|
||||
$I->wait(2);
|
||||
$I->waitForElementVisible($post4Selector);
|
||||
|
||||
$I->wait(20);
|
||||
|
||||
$I->see('POST4', '.s2_streamContent > [data-stream-entry]:nth-of-type(1)');
|
||||
$I->see('POST5', '.s2_streamContent > [data-stream-entry]:nth-of-type(2)');
|
||||
$I->see('POST3', '.s2_streamContent > [data-stream-entry]:nth-of-type(3)');
|
||||
$I->see('POST2', '.s2_streamContent > [data-stream-entry]:nth-of-type(4)');
|
||||
$I->see('POST1', '.s2_streamContent > [data-stream-entry]:nth-of-type(5)');
|
||||
}
|
||||
|
||||
// Sorting
|
||||
// Filtering
|
||||
// multi click logic
|
||||
// empty form
|
||||
|
@ -34,7 +34,7 @@ $this->registerJsVar('defaultStreamSort', ($defaultStreamSort != '') ? $defaultS
|
||||
<?php if ($this->context->showFilters) { ?>
|
||||
<ul class="nav nav-tabs wallFilterPanel" id="filter" style="display: none;">
|
||||
<li class=" dropdown">
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#"><?php echo Yii::t('ContentModule.widgets_views_stream', 'Filter'); ?> <b
|
||||
<a class="stream-filter dropdown-toggle" data-toggle="dropdown" href="#"><?php echo Yii::t('ContentModule.widgets_views_stream', 'Filter'); ?> <b
|
||||
class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<?php foreach ($filters as $filterId => $filterTitle): ?>
|
||||
@ -47,7 +47,7 @@ $this->registerJsVar('defaultStreamSort', ($defaultStreamSort != '') ? $defaultS
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#"><?php echo Yii::t('ContentModule.widgets_views_stream', 'Sorting'); ?>
|
||||
<a class="stream-sorting dropdown-toggle" data-toggle="dropdown" href="#"><?php echo Yii::t('ContentModule.widgets_views_stream', 'Sorting'); ?>
|
||||
<b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#" class="wallSorting" id="sorting_c"><i
|
||||
|
@ -62,13 +62,21 @@ class AcceptanceTester extends \Codeception\Actor
|
||||
$this->amOnPage('index-test.php?r=space/space&sguid=5396d499-20d6-4233-800b-c6c86e5fa34d');
|
||||
}
|
||||
|
||||
public function createPost($text)
|
||||
{
|
||||
$this->click('#contentForm_message_contenteditable');
|
||||
$this->fillField('#contentForm_message_contenteditable', $text);
|
||||
$this->click('#post_submit_button');
|
||||
$this->waitForText($text, 30, '.wall-entry');
|
||||
}
|
||||
|
||||
public function seeSuccess($text = null)
|
||||
{
|
||||
$this->waitForElementVisible('#status-bar .success', 20);
|
||||
$this->waitForElementVisible('#status-bar .success', 30);
|
||||
if ($text) {
|
||||
$this->see($text, '#status-bar');
|
||||
}
|
||||
|
||||
|
||||
$this->waitForElementVisible('#status-bar .status-bar-close');
|
||||
$this->click('#status-bar .status-bar-close');
|
||||
$this->waitForElementNotVisible('#status-bar');
|
||||
@ -80,7 +88,7 @@ class AcceptanceTester extends \Codeception\Actor
|
||||
if ($text) {
|
||||
$this->see($text, '#status-bar');
|
||||
}
|
||||
|
||||
|
||||
$this->waitForElementVisible('#status-bar .status-bar-close');
|
||||
$this->click('#status-bar .status-bar-close');
|
||||
$this->waitForElementNotVisible('#status-bar');
|
||||
@ -103,7 +111,7 @@ class AcceptanceTester extends \Codeception\Actor
|
||||
if ($text) {
|
||||
$this->see($text, '#status-bar');
|
||||
}
|
||||
|
||||
|
||||
$this->waitForElementVisible('#status-bar .status-bar-close');
|
||||
$this->click('#status-bar .status-bar-close');
|
||||
$this->waitForElementNotVisible('#status-bar');
|
||||
@ -174,6 +182,12 @@ class AcceptanceTester extends \Codeception\Actor
|
||||
$this->dontSee($text);
|
||||
$this->click('.notifications');
|
||||
}
|
||||
|
||||
public function scrollTop()
|
||||
{
|
||||
$this->executeJS('window.scrollTo(0,0);');
|
||||
$this->wait(1);
|
||||
}
|
||||
|
||||
public function jsClick($selector)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user