Skip to content
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

[sailfish-browser] Add unit test cases for suffling tabs #209

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions src/webpages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,34 @@ void WebPages::dumpPages() const
qDebug() << "---- end ------";
}

QList<int> WebPages::liveTabs()
{
QList<WebPageEntry *> pages = m_activePages.values();
QList<int> tabIds;
int count = pages.count();
for (int i = 0; i < count; ++i) {
WebPageEntry *pageEntry = pages.at(i);
if (pageEntry->webPage) {
tabIds << pageEntry->webPage->tabId();
}
}
return tabIds;
}

QList<int> WebPages::zombifiedTabs()
{
QMapIterator<int, WebPageEntry*> pages(m_activePages);
QList<int> tabIds;

while (pages.hasNext()) {
pages.next();
if (!pages.value()->webPage) {
tabIds << pages.key();
}
}
return tabIds;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two methods seem to do exactly the same work, but implemented with two different approaches.

I'd probably simplify it a bit: turn it into a list comprehension with a filter. And the list comprehension part could be shared between the methods.


WebPages::WebPageEntry::WebPageEntry(DeclarativeWebPage *webPage, QRectF *cssContentRect)
: webPage(webPage)
, cssContentRect(cssContentRect)
Expand Down
4 changes: 4 additions & 0 deletions src/webpages.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ class WebPages : public QObject
int parentTabId(int tabId) const;
void dumpPages() const;

// Testability helpers
QList<int> liveTabs();
QList<int> zombifiedTabs();

private:
struct WebPageEntry {
WebPageEntry(DeclarativeWebPage *webPage, QRectF *cssContentRect);
Expand Down
2 changes: 1 addition & 1 deletion tests/auto/common/testobject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ void TestObject::init(const QUrl &url)
void TestObject::waitSignals(QSignalSpy &spy, int expectedSignalCount) const
{
int i = 0;
int maxWaits = 10;
int maxWaits = qMax(10, expectedSignalCount);
while (spy.count() < expectedSignalCount && i < maxWaits) {
spy.wait();
++i;
Expand Down
2 changes: 1 addition & 1 deletion tests/auto/tests.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<step>cd /opt/tests/sailfish-browser/auto/ &amp;&amp; ./tst_dbmanager -platform wayland-egl -iterations 10</step>
</case>
<case manual="false" name="webview">
<step>cd /opt/tests/sailfish-browser/auto/ &amp;&amp; ./tst_webview -platform wayland-egl</step>
<step>cd /opt/tests/sailfish-browser/auto/ &amp;&amp; BROWSER_OFFLINE=1 ./tst_webview</step>
</case>
<case manual="false" name="desktopbookmarkwriter">
<step>cd /opt/tests/sailfish-browser/auto/ &amp;&amp; ./tst_desktopbookmarkwriter</step>
Expand Down
166 changes: 165 additions & 1 deletion tests/auto/tst_webview/tst_webview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ class tst_webview : public TestObject

public:
tst_webview();

private slots:
void initTestCase();
void testNewTab_data();
Expand All @@ -42,23 +41,30 @@ private slots:
void clear();
void restart();
void changeTabAndLoad();
void insertOnlinePages_data();
void insertOnlinePages();
void suffleTabsWaitLoaded();
void suffleTabsSwitchImmediately();
void cleanupTestCase();

private:
void activeTabAndLoad(int i);
QString formatUrl(QString fileName) const;
void verifyHistory(QList<TestTab> &historyOrder);

DeclarativeHistoryModel *historyModel;
DeclarativeTabModel *tabModel;
DeclarativeWebContainer *webContainer;
QString baseUrl;
bool offline;
};

tst_webview::tst_webview()
: TestObject()
, historyModel(0)
, tabModel(0)
, webContainer(0)
, offline(getenv("BROWSER_OFFLINE"))
{
}

Expand Down Expand Up @@ -674,6 +680,130 @@ void tst_webview::changeTabAndLoad()
QCOMPARE(webContainer->m_webPages->m_activePages.count(), 2);
}

void tst_webview::insertOnlinePages_data()
{
QSignalSpy tabsCleared(tabModel, SIGNAL(tabsCleared()));
tabModel->clear();
QTest::qWait(1000);
waitSignals(tabsCleared, 1);
QVERIFY(tabModel->count() == 0);

webContainer->setProperty("maxLiveTabCount", 3);
QTest::addColumn<QString>("newUrl");
QTest::addColumn<int>("liveTabCount");

QTest::newRow("google.com") << "http://www.google.com" << 1;
QTest::newRow("m.engadget.com") << "http://m.engadget.com" << 2;
QTest::newRow("yahoo.com") << "http://www.yahoo.com" << 3;
QTest::newRow("facebook.com") << "http://m.facebook.com" << 3;
}

void tst_webview::insertOnlinePages()
{
if (offline) {
QEXPECT_FAIL("", "This cannot be executed without network", Abort);
QCOMPARE(false, true);
}

QFETCH(QString, newUrl);
QFETCH(int, liveTabCount);

QSignalSpy urlChangedSpy(webContainer, SIGNAL(urlChanged()));
QSignalSpy tabCountSpy(tabModel, SIGNAL(countChanged()));
QSignalSpy activeTabChangedSpy(tabModel, SIGNAL(activeTabChanged(int,int)));
QSignalSpy tabAddedSpy(tabModel, SIGNAL(tabAdded(int)));
QSignalSpy contentItemSpy(webContainer, SIGNAL(contentItemChanged()));
QSignalSpy loadingChanged(webContainer, SIGNAL(loadingChanged()));

tabModel->newTab(newUrl, "");

// Wait for MozView instance change.
waitSignals(contentItemSpy, 1);
QCOMPARE(contentItemSpy.count(), 1);

// Load started and ended
waitSignals(loadingChanged, 2);

// ~last in the sequence of adding a new tab.
waitSignals(tabAddedSpy, 1);

// Ignore possible redirection by checking that at least one url and one title change were emitted.
QVERIFY(urlChangedSpy.count() > 0);
QCOMPARE(tabCountSpy.count(), 1);

QCOMPARE(webContainer->m_webPages->liveTabs().count(), liveTabCount);
QCOMPARE(activeTabChangedSpy.count(), 1);
}

void tst_webview::suffleTabsWaitLoaded()
{
if (offline) {
QEXPECT_FAIL("", "This cannot be executed without network", Abort);
QCOMPARE(false, true);
}

// Loops through 4 tabs so that in every 2nd round we pick inactive tab and after which we
// pick zombified tab.
for (int i = 0; i < 4; ++i) {
QSignalSpy loadingChanged(webContainer, SIGNAL(loadingChanged()));
QSignalSpy activeTabChangedSpy(tabModel, SIGNAL(activeTabChanged(int,int,bool)));

activeTabAndLoad(i);

QCOMPARE(activeTabChangedSpy.count(), 1);
waitSignals(loadingChanged, 2);
QVERIFY(webContainer->webPage());
QVERIFY(!webContainer->webPage()->loading());
QVERIFY(webContainer->webPage()->property("loaded").toBool());
}
}

void tst_webview::suffleTabsSwitchImmediately()
{
if (offline) {
QEXPECT_FAIL("", "This cannot be executed without network", Abort);
QCOMPARE(false, true);
}

// Loops through 4 tabs so that in every 2nd round we pick inactive tab and after which we
// pick zombified tab.
for (int i = 0; i < 4; ++i) {
QSignalSpy activeTabChangedSpy(tabModel, SIGNAL(activeTabChanged(int,int,bool)));
QSignalSpy loadProgressSpy(webContainer, SIGNAL(loadProgressChanged()));

activeTabAndLoad(i);
QCOMPARE(activeTabChangedSpy.count(), 1);
QVERIFY(webContainer->webPage());

// Let loading to proceed to 90%
int i = 0;
while (i < 90 && webContainer->loadProgress() < 90) {
loadProgressSpy.wait();
++i;
}

QVERIFY(webContainer->loadProgress() >= 90);
}

// Go through all zombie tabs so that each of them get fully loaded.
for (int i = 0; i < 4; ++i) {
QSignalSpy activeTabChangedSpy(tabModel, SIGNAL(activeTabChanged(int,int,bool)));

QList<int> zombifiedTabs = webContainer->m_webPages->zombifiedTabs();
QCOMPARE(zombifiedTabs.count(), 1);
int tabId = zombifiedTabs.at(0);
tabModel->activateTabById(tabId);
QSignalSpy loadingChanged(webContainer, SIGNAL(loadingChanged()));
QCOMPARE(activeTabChangedSpy.count(), 1);

// 60secs of timeout per loading change.
waitSignals(loadingChanged, 2, 60000);
QVERIFY(webContainer->webPage());
QVERIFY(!webContainer->webPage()->loading());
QVERIFY(webContainer->webPage()->property("loaded").toBool());
}
}

void tst_webview::cleanupTestCase()
{
QTest::qWait(1000);
Expand Down Expand Up @@ -715,6 +845,40 @@ void tst_webview::verifyHistory(QList<TestTab> &historyOrder)
}
}

// Used with suffleTabsWaitLoaded and suffleTabsSwitchImmediately (4 tabs)
void tst_webview::activeTabAndLoad(int i)
{
int tabId = -1;
bool reload = false;
if (i % 2 == 0) {
// Inactive and not current tab
QList<int> liveTabs = webContainer->m_webPages->liveTabs();
QCOMPARE(liveTabs.count(), 3);
tabId = liveTabs.at(random(0, 2));

while (tabId == webContainer->tabId()) {
tabId = liveTabs.at(random(0, 2));
}
reload = true;
} else {
// First and last zombified tab.
QList<int> zombifiedTabs = webContainer->m_webPages->zombifiedTabs();
QCOMPARE(zombifiedTabs.count(), 1);
tabId = zombifiedTabs.at(0);
}

tabModel->activateTabById(tabId);

QVERIFY(webContainer->webPage());
QSignalSpy loadingSpy(webContainer->webPage(), SIGNAL(loadingChanged()));

// Reload inactive tab.
if (reload) {
webContainer->webPage()->reload();
}
waitSignals(loadingSpy, 1);
}

int main(int argc, char *argv[])
{
setenv("USE_ASYNC", "1", 1);
Expand Down
7 changes: 7 additions & 0 deletions tests/auto/tst_webview/tst_webview.qml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ ApplicationWindow {
active: true
toolbarHeight: 50
portrait: true
width: parent.width
height: parent.height

onLoadProgressChanged: console.log("progress:", loadProgress, url, tabId)
onLoadingChanged: console.log(loading, url, tabId)
onUrlChanged: console.log(url, tabId)
onContentItemChanged: console.log(contentItem, "url:", (contentItem ? contentItem.url : "no url" ), "tabId:", (contentItem ? contentItem.tabId : -1 ))

HistoryModel {
id: historyModel
Expand Down