diff options
-rw-r--r-- | js/piwik.js | 2 | ||||
-rw-r--r-- | piwik.js | 2 | ||||
-rw-r--r-- | plugins/CoreHome/javascripts/top_controls.js | 25 | ||||
-rw-r--r-- | plugins/DBStats/tests/UI/expected-ui-screenshots/DBStats_admin_page.png | bin | 312771 -> 198182 bytes | |||
-rw-r--r-- | plugins/SitesManager/API.php | 4 | ||||
-rw-r--r-- | tests/PHPUnit/Fixture.php | 13 | ||||
-rw-r--r-- | tests/PHPUnit/Fixtures/ManySitesImportedLogsWithXssAttempts.php | 98 | ||||
-rw-r--r-- | tests/PHPUnit/Fixtures/UITestFixture.php | 80 | ||||
-rw-r--r-- | tests/PHPUnit/TestingEnvironment.php | 6 | ||||
m--------- | tests/PHPUnit/UI | 0 | ||||
-rw-r--r-- | tests/lib/screenshot-testing/support/page-renderer.js | 32 | ||||
-rw-r--r-- | tests/lib/screenshot-testing/support/test-environment.js | 13 | ||||
-rw-r--r-- | tests/resources/screenshot-override/override.css | 8 | ||||
-rwxr-xr-x | tests/travis/upload_artifacts.sh | 4 |
14 files changed, 161 insertions, 126 deletions
diff --git a/js/piwik.js b/js/piwik.js index 406894b9b6..5fbee7b4ff 100644 --- a/js/piwik.js +++ b/js/piwik.js @@ -999,7 +999,7 @@ if (typeof Piwik !== 'object') { // check whether we were redirected from the piwik overlay plugin var referrerRegExp = new RegExp('index\\.php\\?module=Overlay&action=startOverlaySession' - + '&idsite=([0-9]+)&period=([^&]+)&date=([^&]+)$'); + + '&idSite=([0-9]+)&period=([^&]+)&date=([^&]+)$'); var match = referrerRegExp.exec(documentAlias.referrer); @@ -14,7 +14,7 @@ return typeof f==="function"?m({"":n},""):n}throw new SyntaxError("JSON2.parse") }while(O.getTimeAlias()<h)}}function I(){var O;if(!m){m=true;H("load");for(O=0;O<y.length;O++){y[O]()}}return true}function l(){var P;if(q.addEventListener){M(q,"DOMContentLoaded",function O(){q.removeEventListener("DOMContentLoaded",O,false);I()})}else{if(q.attachEvent){q.attachEvent("onreadystatechange",function O(){if(q.readyState==="complete"){q.detachEvent("onreadystatechange",O);I()}});if(q.documentElement.doScroll&&A===A.top){(function O(){if(!m){try{q.documentElement.doScroll("left")}catch(Q){setTimeout(O,0);return}I()}}())}}}if((new RegExp("WebKit")).test(d.userAgent)){P=setInterval(function(){if(m||/loaded|complete/.test(q.readyState)){clearInterval(P);I()}},10)}M(A,"load",I,false)}function g(Q,P){var O=q.createElement("script");O.type="text/javascript";O.src=Q;if(O.readyState){O.onreadystatechange=function(){var R=this.readyState;if(R==="loaded"||R==="complete"){O.onreadystatechange=null;P()}}}else{O.onload=P}q.getElementsByTagName("head")[0].appendChild(O)}function t(){var O=""; try{O=A.top.document.referrer}catch(Q){if(A.parent){try{O=A.parent.document.referrer}catch(P){O=""}}}if(O===""){O=q.referrer}return O}function i(O){var Q=new RegExp("^([a-z]+):"),P=Q.exec(O);return P?P[1]:null}function b(O){var Q=new RegExp("^(?:(?:https?|ftp):)/*(?:[^@]+@)?([^:/#]+)"),P=Q.exec(O);return P?P[1]:O}function B(Q,P){var O="[\\?&#]"+P+"=([^&#]*)";var S=new RegExp(O);var R=S.exec(Q);return R?z(R[1]):""}function o(O){return f(j(O))}function L(ae){var Q=function(aj,W){return(aj<<W)|(aj>>>(32-W))},af=function(al){var aj="",ak,W;for(ak=7;ak>=0;ak--){W=(al>>>(ak*4))&15;aj+=W.toString(16)}return aj},T,ah,ag,P=[],Y=1732584193,V=4023233417,U=2562383102,S=271733878,R=3285377520,ad,ac,ab,aa,Z,ai,O,X=[];ae=o(ae);O=ae.length;for(ah=0;ah<O-3;ah+=4){ag=ae.charCodeAt(ah)<<24|ae.charCodeAt(ah+1)<<16|ae.charCodeAt(ah+2)<<8|ae.charCodeAt(ah+3);X.push(ag)}switch(O&3){case 0:ah=2147483648;break;case 1:ah=ae.charCodeAt(O-1)<<24|8388608;break;case 2:ah=ae.charCodeAt(O-2)<<24|ae.charCodeAt(O-1)<<16|32768; break;case 3:ah=ae.charCodeAt(O-3)<<24|ae.charCodeAt(O-2)<<16|ae.charCodeAt(O-1)<<8|128;break}X.push(ah);while((X.length&15)!==14){X.push(0)}X.push(O>>>29);X.push((O<<3)&4294967295);for(T=0;T<X.length;T+=16){for(ah=0;ah<16;ah++){P[ah]=X[T+ah]}for(ah=16;ah<=79;ah++){P[ah]=Q(P[ah-3]^P[ah-8]^P[ah-14]^P[ah-16],1)}ad=Y;ac=V;ab=U;aa=S;Z=R;for(ah=0;ah<=19;ah++){ai=(Q(ad,5)+((ac&ab)|(~ac&aa))+Z+P[ah]+1518500249)&4294967295;Z=aa;aa=ab;ab=Q(ac,30);ac=ad;ad=ai}for(ah=20;ah<=39;ah++){ai=(Q(ad,5)+(ac^ab^aa)+Z+P[ah]+1859775393)&4294967295;Z=aa;aa=ab;ab=Q(ac,30);ac=ad;ad=ai}for(ah=40;ah<=59;ah++){ai=(Q(ad,5)+((ac&ab)|(ac&aa)|(ab&aa))+Z+P[ah]+2400959708)&4294967295;Z=aa;aa=ab;ab=Q(ac,30);ac=ad;ad=ai}for(ah=60;ah<=79;ah++){ai=(Q(ad,5)+(ac^ab^aa)+Z+P[ah]+3395469782)&4294967295;Z=aa;aa=ab;ab=Q(ac,30);ac=ad;ad=ai}Y=(Y+ad)&4294967295;V=(V+ac)&4294967295;U=(U+ab)&4294967295;S=(S+aa)&4294967295;R=(R+Z)&4294967295}ai=af(Y)+af(V)+af(U)+af(S)+af(R);return ai.toLowerCase()}function G(Q,O,P){if(Q==="translate.googleusercontent.com"){if(P===""){P=O -}O=B(O,"u");Q=b(O)}else{if(Q==="cc.bingj.com"||Q==="webcache.googleusercontent.com"||Q.slice(0,5)==="74.6."){O=q.links[0].href;Q=b(O)}}return[Q,O,P]}function u(P){var O=P.length;if(P.charAt(--O)==="."){P=P.slice(0,O)}if(P.slice(0,2)==="*."){P=P.slice(1)}return P}function N(P){P=P&&P.text?P.text:P;if(!k(P)){var O=q.getElementsByTagName("title");if(O&&s(O[0])){P=O[0].text}}return P}function w(O,P){if(P){return P}if(O.slice(-9)==="piwik.php"){O=O.slice(0,O.length-9)}return O}function v(S){var O="Piwik_Overlay";var V=new RegExp("index\\.php\\?module=Overlay&action=startOverlaySession&idsite=([0-9]+)&period=([^&]+)&date=([^&]+)$");var Q=V.exec(q.referrer);if(Q){var R=Q[1];if(R!==String(S)){return false}var U=Q[2],P=Q[3];A.name=O+"###"+U+"###"+P}var T=A.name.split("###");return T.length===3&&T[0]===O}function F(P,U,R){var T=A.name.split("###"),S=T[1],O=T[2],Q=w(P,U);g(Q+"plugins/Overlay/client/client.js?v=1",function(){Piwik_Overlay_Client.initialize(Q,R,S,O)})}function x(am,aN){var U=G(q.domain,A.location.href,t()),a7=u(U[0]),bm=U[1],aU=U[2],aS="GET",S=am||"",aj="",aP="",bc=aN||"",aE,au=q.title,aw="7z|aac|apk|ar[cj]|as[fx]|avi|bin|csv|deb|dmg|docx?|exe|flv|gif|gz|gzip|hqx|jar|jpe?g|js|mp(2|3|4|e?g)|mov(ie)?|ms[ip]|od[bfgpst]|og[gv]|pdf|phps|png|pptx?|qtm?|ra[mr]?|rpm|sea|sit|tar|t?bz2?|tgz|torrent|txt|wav|wm[av]|wpd||xlsx?|xml|z|zip",aQ=[a7],X=[],aI=[],al=[],aO=500,Y,an,Z,ab,ay=["pk_campaign","piwik_campaign","utm_campaign","utm_source","utm_medium"],at=["pk_kwd","piwik_kwd","utm_term"],bk="_pk_",ae,bl,ac=false,bf,aA,aD,ai=63072000000,ak=1800000,aF=15768000000,aB=true,ap=0,W=false,aJ={},T={},bg=200,a0={},bd={},aX=false,aV=false,aT,aK,af,ax=L,aW,aC; +}O=B(O,"u");Q=b(O)}else{if(Q==="cc.bingj.com"||Q==="webcache.googleusercontent.com"||Q.slice(0,5)==="74.6."){O=q.links[0].href;Q=b(O)}}return[Q,O,P]}function u(P){var O=P.length;if(P.charAt(--O)==="."){P=P.slice(0,O)}if(P.slice(0,2)==="*."){P=P.slice(1)}return P}function N(P){P=P&&P.text?P.text:P;if(!k(P)){var O=q.getElementsByTagName("title");if(O&&s(O[0])){P=O[0].text}}return P}function w(O,P){if(P){return P}if(O.slice(-9)==="piwik.php"){O=O.slice(0,O.length-9)}return O}function v(S){var O="Piwik_Overlay";var V=new RegExp("index\\.php\\?module=Overlay&action=startOverlaySession&idSite=([0-9]+)&period=([^&]+)&date=([^&]+)$");var Q=V.exec(q.referrer);if(Q){var R=Q[1];if(R!==String(S)){return false}var U=Q[2],P=Q[3];A.name=O+"###"+U+"###"+P}var T=A.name.split("###");return T.length===3&&T[0]===O}function F(P,U,R){var T=A.name.split("###"),S=T[1],O=T[2],Q=w(P,U);g(Q+"plugins/Overlay/client/client.js?v=1",function(){Piwik_Overlay_Client.initialize(Q,R,S,O)})}function x(am,aN){var U=G(q.domain,A.location.href,t()),a7=u(U[0]),bm=U[1],aU=U[2],aS="GET",S=am||"",aj="",aP="",bc=aN||"",aE,au=q.title,aw="7z|aac|apk|ar[cj]|as[fx]|avi|bin|csv|deb|dmg|docx?|exe|flv|gif|gz|gzip|hqx|jar|jpe?g|js|mp(2|3|4|e?g)|mov(ie)?|ms[ip]|od[bfgpst]|og[gv]|pdf|phps|png|pptx?|qtm?|ra[mr]?|rpm|sea|sit|tar|t?bz2?|tgz|torrent|txt|wav|wm[av]|wpd||xlsx?|xml|z|zip",aQ=[a7],X=[],aI=[],al=[],aO=500,Y,an,Z,ab,ay=["pk_campaign","piwik_campaign","utm_campaign","utm_source","utm_medium"],at=["pk_kwd","piwik_kwd","utm_term"],bk="_pk_",ae,bl,ac=false,bf,aA,aD,ai=63072000000,ak=1800000,aF=15768000000,aB=true,ap=0,W=false,aJ={},T={},bg=200,a0={},bd={},aX=false,aV=false,aT,aK,af,ax=L,aW,aC; function a2(bv,bs,br,bu,bq,bt){if(ac){return}var bp;if(br){bp=new Date();bp.setTime(bp.getTime()+br)}q.cookie=bv+"="+j(bs)+(br?";expires="+bp.toGMTString():"")+";path="+(bu||"/")+(bq?";domain="+bq:"")+(bt?";secure":"")}function ah(br){if(ac){return 0}var bp=new RegExp("(^|;)[ ]*"+br+"=([^;]*)"),bq=bp.exec(q.cookie);return bq?z(bq[2]):0}function bh(bp){var bq;if(Z){bq=new RegExp("#.*");return bp.replace(bq,"")}return bp}function a6(br,bp){var bs=i(bp),bq;if(bs){return bp}if(bp.slice(0,1)==="/"){return i(br)+"://"+b(br)+bp}br=bh(br);bq=br.indexOf("?");if(bq>=0){br=br.slice(0,bq)}bq=br.lastIndexOf("/");if(bq!==br.length-1){br=br.slice(0,bq+1)}return br+bp}function aR(bs){var bq,bp,br;for(bq=0;bq<aQ.length;bq++){bp=u(aQ[bq].toLowerCase());if(bs===bp){return true}if(bp.slice(0,1)==="."){if(bs===bp.slice(1)){return true}br=bs.length-bp.length;if((br>0)&&(bs.slice(br)===bp)){return true}}}return false}function bo(bp){var bq=new Image(1,1);bq.onload=function(){p=0};bq.src=S+(S.indexOf("?")<0?"?":"&")+bp }function a3(bp){try{var br=A.XMLHttpRequest?new A.XMLHttpRequest():A.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):null;br.open("POST",S,true);br.onreadystatechange=function(){if(this.readyState===4&&this.status!==200){bo(bp)}};br.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");br.send(bp)}catch(bq){bo(bp)}}function az(br,bq){var bp=new Date();if(!bf){if(aS==="POST"){a3(br)}else{bo(br)}h=bp.getTime()+bq}}function a1(bp){return bk+bp+"."+bc+"."+aW}function V(){if(ac){return"0"}if(!s(d.cookieEnabled)){var bp=a1("testcookie");a2(bp,"1");return ah(bp)==="1"?"1":"0"}return d.cookieEnabled?"1":"0"}function aL(){aW=ax((ae||a7)+(bl||"/")).slice(0,4)}function ag(){var bq=a1("cvar"),bp=ah(bq);if(bp.length){bp=JSON2.parse(bp);if(C(bp)){return bp}}return{}}function R(){if(W===false){W=ag()}}function bb(){var bp=new Date();aT=bp.getTime()}function ad(bt,bq,bp,bs,br,bu){a2(a1("id"),bt+"."+bq+"."+bp+"."+bs+"."+br+"."+bu,ai,bl,ae)}function Q(){var bq=new Date(),bp=Math.round(bq.getTime()/1000),bs=ah(a1("id")),br; if(bs){br=bs.split(".");br.unshift("0")}else{if(!aC){aC=ax((d.userAgent||"")+(d.platform||"")+JSON2.stringify(bd)+bq.getTime()+Math.random()).slice(0,16)}br=["1",aC,bp,0,bp,"",""]}return br}function O(){var bp=ah(a1("ref"));if(bp.length){try{bp=JSON2.parse(bp);if(C(bp)){return bp}}catch(bq){}}return["","",0,""]}function P(){var bp=ac;ac=false;a2(a1("id"),"",-86400,bl,ae);a2(a1("ses"),"",-86400,bl,ae);a2(a1("cvar"),"",-86400,bl,ae);a2(a1("ref"),"",-86400,bl,ae);ac=bp}function ba(bt){if(!bt||!C(bt)){return}var bs=[];var br;for(br in bt){if(Object.prototype.hasOwnProperty.call(bt,br)){bs.push(br)}}var bu={};bs.sort();var bp=bs.length;var bq;for(bq=0;bq<bp;bq++){bu[bs[bq]]=bt[bs[bq]]}return bu}function av(br,bP,bQ,bs){var bN,bq=new Date(),bz=Math.round(bq.getTime()/1000),bT,bO,bu,bF,bK,by,bI,bv,bM,bt=1024,bV,bC,bJ=W,bA=a1("ses"),bB=a1("ref"),bW=a1("cvar"),bG=Q(),bE=ah(bA),bL=O(),bS=aE||bm,bw,bp;if(ac){P()}if(bf){return""}bT=bG[0];bO=bG[1];bF=bG[2];bu=bG[3];bK=bG[4];by=bG[5];if(!s(bG[6])){bG[6]="" diff --git a/plugins/CoreHome/javascripts/top_controls.js b/plugins/CoreHome/javascripts/top_controls.js index c2089648d0..21f3c41fc6 100644 --- a/plugins/CoreHome/javascripts/top_controls.js +++ b/plugins/CoreHome/javascripts/top_controls.js @@ -7,18 +7,21 @@ function initTopControls() { var $topControlsContainer = $('.top_controls'), left = 0; - $('.piwikTopControl').each(function () { - var $control = $(this); - if ($control.css('display') == 'none') { - return; - } + + if ($topControlsContainer.length) { + $('.piwikTopControl').each(function () { + var $control = $(this); + if ($control.css('display') == 'none') { + return; + } - $control.css('left', left); + $control.css('left', left); - if (!$.contains($topControlsContainer[0], this)) { - $control.detach().appendTo($topControlsContainer); - } + if (!$.contains($topControlsContainer[0], this)) { + $control.detach().appendTo($topControlsContainer); + } - left += $control.outerWidth(true); - }); + left += $control.outerWidth(true); + }); + } }
\ No newline at end of file diff --git a/plugins/DBStats/tests/UI/expected-ui-screenshots/DBStats_admin_page.png b/plugins/DBStats/tests/UI/expected-ui-screenshots/DBStats_admin_page.png Binary files differindex 6d1e0ba667..86e8c4e5c5 100644 --- a/plugins/DBStats/tests/UI/expected-ui-screenshots/DBStats_admin_page.png +++ b/plugins/DBStats/tests/UI/expected-ui-screenshots/DBStats_admin_page.png diff --git a/plugins/SitesManager/API.php b/plugins/SitesManager/API.php index 1eeb47ffca..1239c50489 100644 --- a/plugins/SitesManager/API.php +++ b/plugins/SitesManager/API.php @@ -727,14 +727,14 @@ class API extends \Piwik\Plugin\API * * @return int the number of inserted URLs */ - public function setSiteAliasUrls($idSite, $urls) + public function setSiteAliasUrls($idSite, $urls = array()) { Piwik::checkUserHasAdminAccess($idSite); $urls = $this->cleanParameterUrls($urls); $this->checkUrls($urls); - $this->deleteSiteAliasUrls($idSite); + $this->deleteSiteAliasUrls($idSite); $this->insertSiteUrls($idSite, $urls); $this->postUpdateWebsite($idSite); diff --git a/tests/PHPUnit/Fixture.php b/tests/PHPUnit/Fixture.php index cde82728f5..501645bc3e 100644 --- a/tests/PHPUnit/Fixture.php +++ b/tests/PHPUnit/Fixture.php @@ -181,6 +181,8 @@ class Fixture extends PHPUnit_Framework_Assert return; } + $this->testEnvironment->save(); + if ($this->overwriteExisting || !$this->isFixtureSetUp() ) { @@ -697,6 +699,17 @@ class Fixture extends PHPUnit_Framework_Assert echo $message . "\n"; } } + + // NOTE: since API_Request does sanitization, API methods do not. when calling them, we must + // sometimes do sanitization ourselves. + public static function makeXssContent($type, $sanitize = false) + { + $result = "<script>$('body').html('$type XSS!');</script>"; + if ($sanitize) { + $result = Common::sanitizeInputValue($result); + } + return $result; + } } // TODO: remove when other plugins don't use BaseFixture diff --git a/tests/PHPUnit/Fixtures/ManySitesImportedLogsWithXssAttempts.php b/tests/PHPUnit/Fixtures/ManySitesImportedLogsWithXssAttempts.php index da4bbdf827..8eaa9d5cb7 100644 --- a/tests/PHPUnit/Fixtures/ManySitesImportedLogsWithXssAttempts.php +++ b/tests/PHPUnit/Fixtures/ManySitesImportedLogsWithXssAttempts.php @@ -35,7 +35,6 @@ class Test_Piwik_Fixture_ManySitesImportedLogsWithXssAttempts extends Test_Piwik $this->trackVisitsForRealtimeMap(Date::factory('2012-08-11 11:22:33'), $createSeperateVisitors = false); - $this->setupDashboards(); $this->setupXssSegment(); $this->addAnnotations(); $this->trackVisitsForRealtimeMap($this->now); @@ -60,92 +59,6 @@ class Test_Piwik_Fixture_ManySitesImportedLogsWithXssAttempts extends Test_Piwik } } - /** Creates two dashboards that split the widgets up into different groups. */ - public function setupDashboards() - { - $dashboardColumnCount = 3; - $dashboardCount = 4; - - $layout = array(); - for ($j = 0; $j != $dashboardColumnCount; ++$j) { - $layout[] = array(); - } - - $dashboards = array(); - for ($i = 0; $i != $dashboardCount; ++$i) { - $dashboards[] = $layout; - } - - $oldGet = $_GET; - $_GET['idSite'] = $this->idSite; - - // collect widgets & sort them so widget order is not important - $allWidgets = array(); - foreach (WidgetsList::get() as $category => $widgets) { - $allWidgets = array_merge($allWidgets, $widgets); - } - usort($allWidgets, function ($lhs, $rhs) { - return strcmp($lhs['uniqueId'], $rhs['uniqueId']); - }); - - // group widgets so they will be spread out across 3 dashboards - $groupedWidgets = array(); - $dashboard = 0; - foreach ($allWidgets as $widget) { - if ($widget['uniqueId'] == 'widgetSEOgetRank' - || $widget['uniqueId'] == 'widgetReferrersgetKeywordsForPage' - || $widget['uniqueId'] == 'widgetLivegetVisitorProfilePopup' - || $widget['uniqueId'] == 'widgetActionsgetPageTitles' - || strpos($widget['uniqueId'], 'widgetExample') === 0 - ) { - continue; - } - - $dashboard = ($dashboard + 1) % $dashboardCount; - - $widgetEntry = array( - 'uniqueId' => $widget['uniqueId'], - 'parameters' => $widget['parameters'] - ); - - // dashboard images must have height of less than 4000px to avoid odd discoloration of last line of image - $widgetEntry['parameters']['filter_limit'] = 5; - - $groupedWidgets[$dashboard][] = $widgetEntry; - } - - // distribute widgets in each dashboard - $column = 0; - foreach ($groupedWidgets as $dashboardIndex => $dashboardWidgets) { - foreach ($dashboardWidgets as $widget) { - $column = ($column + 1) % $dashboardColumnCount; - - $dashboards[$dashboardIndex][$column][] = $widget; - } - } - - foreach ($dashboards as $id => $layout) { - if ($id == 0) { - $_GET['name'] = self::makeXssContent('dashboard name' . $id); - } else { - $_GET['name'] = 'dashboard name' . $id; - } - $_GET['layout'] = Common::json_encode($layout); - $_GET['idDashboard'] = $id + 1; - FrontController::getInstance()->fetchDispatch('Dashboard', 'saveLayout'); - } - - $allWidgets = array(); - foreach (WidgetsList::get() as $category => $widgets) { - $allWidgets = array_merge($allWidgets, $widgets); - } - usort($allWidgets, function ($lhs, $rhs) { - return strcmp($lhs['uniqueId'], $rhs['uniqueId']); - }); - - $_GET = $oldGet; - } - public function setupXssSegment() { $segmentName = self::makeXssContent('segment'); @@ -223,15 +136,4 @@ class Test_Piwik_Fixture_ManySitesImportedLogsWithXssAttempts extends Test_Piwik $t->setLongitude(-46.64); self::checkResponse($t->doTrackPageView('incredible title!')); } - - // NOTE: since API_Request does sanitization, API methods do not. when calling them, we must - // sometimes do sanitization ourselves. - public static function makeXssContent($type, $sanitize = false) - { - $result = "<script>$('body').html('$type XSS!');</script>"; - if ($sanitize) { - $result = Common::sanitizeInputValue($result); - } - return $result; - } } diff --git a/tests/PHPUnit/Fixtures/UITestFixture.php b/tests/PHPUnit/Fixtures/UITestFixture.php index 4c70599fff..10111b8933 100644 --- a/tests/PHPUnit/Fixtures/UITestFixture.php +++ b/tests/PHPUnit/Fixtures/UITestFixture.php @@ -18,6 +18,7 @@ use Piwik\Db; use Piwik\FrontController; use Piwik\Option; use Piwik\Url; +use Piwik\WidgetsList; /** * Fixture for UI tests. @@ -36,7 +37,6 @@ class UITestFixture extends OmniFixture $this->addOverlayVisits(); $this->addNewSitesForSiteSelector(); - $this->createEmptyDashboard(); DbHelper::createAnonymousUser(); UsersManagerAPI::getInstance()->setSuperUserAccess('superUserLogin', true); @@ -53,6 +53,8 @@ class UITestFixture extends OmniFixture { parent::performSetUp($testCase, $setupEnvironmentOnly); + $this->setupDashboards(); + AssetManager::getInstance()->removeMergedAssets(); $visitorIdDeterministic = bin2hex(Db::fetchOne( @@ -74,9 +76,6 @@ class UITestFixture extends OmniFixture private function addOverlayVisits() { - $alias = Url::getCurrentScheme() . '://' . Url::getCurrentHost(); - SitesManagerAPI::getInstance()->addSiteAliasUrls($idSite = 3, array($alias)); - $baseUrl = $this->getLocalTestSiteUrl(); $visitProfiles = array( @@ -165,9 +164,80 @@ class UITestFixture extends OmniFixture } } - private function createEmptyDashboard() + /** Creates two dashboards that split the widgets up into different groups. */ + public function setupDashboards() { + $dashboardColumnCount = 3; + $dashboardCount = 4; + + $layout = array(); + for ($j = 0; $j != $dashboardColumnCount; ++$j) { + $layout[] = array(); + } + + $dashboards = array(); + for ($i = 0; $i != $dashboardCount; ++$i) { + $dashboards[] = $layout; + } + $oldGet = $_GET; + $_GET['idSite'] = 1; + + // collect widgets & sort them so widget order is not important + $allWidgets = array(); + foreach (WidgetsList::get() as $category => $widgets) { + $allWidgets = array_merge($allWidgets, $widgets); + } + usort($allWidgets, function ($lhs, $rhs) { + return strcmp($lhs['uniqueId'], $rhs['uniqueId']); + }); + + // group widgets so they will be spread out across 3 dashboards + $groupedWidgets = array(); + $dashboard = 0; + foreach ($allWidgets as $widget) { + if ($widget['uniqueId'] == 'widgetSEOgetRank' + || $widget['uniqueId'] == 'widgetReferrersgetKeywordsForPage' + || $widget['uniqueId'] == 'widgetLivegetVisitorProfilePopup' + || $widget['uniqueId'] == 'widgetActionsgetPageTitles' + || strpos($widget['uniqueId'], 'widgetExample') === 0 + ) { + continue; + } + + $dashboard = ($dashboard + 1) % $dashboardCount; + + $widgetEntry = array( + 'uniqueId' => $widget['uniqueId'], + 'parameters' => $widget['parameters'] + ); + + // dashboard images must have height of less than 4000px to avoid odd discoloration of last line of image + $widgetEntry['parameters']['filter_limit'] = 5; + + $groupedWidgets[$dashboard][] = $widgetEntry; + } + + // distribute widgets in each dashboard + $column = 0; + foreach ($groupedWidgets as $dashboardIndex => $dashboardWidgets) { + foreach ($dashboardWidgets as $widget) { + $column = ($column + 1) % $dashboardColumnCount; + + $dashboards[$dashboardIndex][$column][] = $widget; + } + } + + foreach ($dashboards as $id => $layout) { + if ($id == 0) { + $_GET['name'] = self::makeXssContent('dashboard name' . $id); + } else { + $_GET['name'] = 'dashboard name' . $id; + } + $_GET['layout'] = Common::json_encode($layout); + $_GET['idDashboard'] = $id + 1; + FrontController::getInstance()->fetchDispatch('Dashboard', 'saveLayout'); + } // create empty dashboard $dashboard = array( diff --git a/tests/PHPUnit/TestingEnvironment.php b/tests/PHPUnit/TestingEnvironment.php index d13f918516..91567d0eb4 100644 --- a/tests/PHPUnit/TestingEnvironment.php +++ b/tests/PHPUnit/TestingEnvironment.php @@ -90,6 +90,12 @@ class Piwik_TestingEnvironment \Piwik\Config::$defaultGlobalConfigPath = $testingEnvironment->configFileGlobal; } + if ($testingEnvironment->queryParamOverride) { + foreach ($testingEnvironment->queryParamOverride as $key => $value) { + $_GET[$key] = $value; + } + } + Piwik::addAction('Access.createAccessSingleton', function($access) use ($testingEnvironment) { if (!$testingEnvironment->testUseRegularAuth) { $access = new Piwik_MockAccess($access); diff --git a/tests/PHPUnit/UI b/tests/PHPUnit/UI -Subproject febab342e3476848151d407f6a987504f0ca3a4 +Subproject 9b536e38844b70137cbf871b0739d4e4bced7a9 diff --git a/tests/lib/screenshot-testing/support/page-renderer.js b/tests/lib/screenshot-testing/support/page-renderer.js index 7292205abc..775a205a05 100644 --- a/tests/lib/screenshot-testing/support/page-renderer.js +++ b/tests/lib/screenshot-testing/support/page-renderer.js @@ -271,6 +271,10 @@ PageRenderer.prototype._getImageLoadingCount = function () { var cssImageProperties = ['backgroundImage', 'listStyleImage', 'borderImage', 'borderCornerImage', 'cursor'], matchUrl = /url\(\s*(['"]?)(.*?)\1\s*\)/g; + if (!window._pendingImages) { + window._pendingImages = {}; + } + // check <img> elements and background URLs var elements = document.getElementsByTagName('*'); for (var i = 0; i != elements.length; ++i) { @@ -281,6 +285,10 @@ PageRenderer.prototype._getImageLoadingCount = function () { count = count + 1; } + if (typeof $ === "undefined") { // waiting for CSS depends on jQuery + continue; + } + for (var j = 0; j != cssImageProperties.length; ++j) { // handle CSS image URLs var prop = $(element).css(cssImageProperties[j]); @@ -289,17 +297,29 @@ PageRenderer.prototype._getImageLoadingCount = function () { } while (match = matchUrl.exec(prop)) { - var src = match[2], - img = new Image(); - img.src = src; - - if (img.complete === false) { - count = count + 1; + var src = match[2]; + if (window._pendingImages[src]) { + continue; } + + var img = new Image(); + + img.addEventListener('load', function () { + window._pendingImages[this.src] = true; + }); + + window._pendingImages[src] = img; + img.src = src; } } } + for (var url in window._pendingImages) { + if (typeof window._pendingImages[url] === 'object') { + count = count + 1; + } + } + return count; }); }; diff --git a/tests/lib/screenshot-testing/support/test-environment.js b/tests/lib/screenshot-testing/support/test-environment.js index 288dc0a886..0bdb52cc21 100644 --- a/tests/lib/screenshot-testing/support/test-environment.js +++ b/tests/lib/screenshot-testing/support/test-environment.js @@ -48,7 +48,14 @@ TestingEnvironment.prototype.callController = function (method, params, done) { TestingEnvironment.prototype._call = function (params, done) { var url = path.join(config.piwikUrl, "tests/PHPUnit/proxy/index.php?"); for (var key in params) { - url += key + "=" + encodeURIComponent(params[key]) + "&"; + var value = params[key]; + if (value instanceof Array) { + for (var i = 0; i != value.length; ++i) { + url += key + "[]=" + encodeURIComponent(value[i]) + "&"; + } + } else { + url += key + "=" + encodeURIComponent(value) + "&"; + } } url = url.substring(0, url.length - 1); @@ -61,6 +68,10 @@ TestingEnvironment.prototype._call = function (params, done) { } catch (e) { throw new Error("Unable to parse JSON response: " + response); } + + if (response.result == "error") { + throw new Error("API returned error: " + response.message); + } } page.close(); diff --git a/tests/resources/screenshot-override/override.css b/tests/resources/screenshot-override/override.css index 9e4dff5d1f..0aea342b74 100644 --- a/tests/resources/screenshot-override/override.css +++ b/tests/resources/screenshot-override/override.css @@ -14,7 +14,13 @@ span.plugin-version { visibility:hidden; } -/* add some space to the top of the segment editor & other widgets so screenshots are clearer */ +/* add some space around the segment editor & other controls so screenshots are clearer */ .widget .segmentEditorPanel, .widget .dashboardSettings, .widget .sites_autocomplete, .widget .periodSelector { margin-top:1em; + margin-bottom:1em; + margin-left:1em; +} + +.widget { + overflow: visible !important; }
\ No newline at end of file diff --git a/tests/travis/upload_artifacts.sh b/tests/travis/upload_artifacts.sh index 6583b385e0..4f577d0948 100755 --- a/tests/travis/upload_artifacts.sh +++ b/tests/travis/upload_artifacts.sh @@ -28,6 +28,10 @@ else if [ -d "./screenshot-diffs" ]; then echo "Uploading screenshot diffs..." + + echo "" + ls screenshot-diffs + echo "" tar -cjf screenshot-diffs.tar.bz2 screenshot-diffs curl -X POST --data-binary @screenshot-diffs.tar.bz2 "$url_base&artifact_name=screenshot-diffs" |