Skip to content
Merged
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
44 changes: 44 additions & 0 deletions phpbb-test-board/feature_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,49 @@ def warnings() -> int:
"moderator can warn once all the user's groups are ticked")


def check_wiki(b: Board) -> None:
# Articles and a post stored through phpBB's own text parser, so the
# extension's [[ ]] markup is parsed exactly as on a real board.
def store(text: str) -> str:
return ("$t = " + json.dumps(text) + "; $uid = $bit = ''; $flags = 0;"
"generate_text_for_storage($t, $uid, $bit, $flags, true, true, true);")

articles = (
("First article", "Read [[Second article]] and [[Missing page|this one]]."),
("Second article", "The second article."),
)
for title, text in articles:
b.php(store(text) + "$db->sql_query('INSERT INTO ' . $table_prefix . 'wiki_article ' . "
"$db->sql_build_array('INSERT', ['article_title' => " + json.dumps(title) + ", 'article_url' => "
+ json.dumps(title) + ", 'article_text' => $t, 'bbcode_uid' => $uid, 'bbcode_bitfield' => $bit, "
"'article_approved' => 1, 'article_user_id' => 2, 'article_last_edit' => time(), "
"'article_time_created' => time(), 'article_sources' => '', 'article_description' => '']));",
check=True)
b.php(store("See [[Second article]].\n[code][[Not a link]][/code]")
+ "$db->sql_query('UPDATE ' . POSTS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', "
"['post_text' => $t, 'bbcode_uid' => $uid, 'bbcode_bitfield' => $bit]) . ' WHERE post_id = 1');",
check=True)
b.purge_cache()

admin = requests.Session()
sid = b.login(admin)
first = admin.get(f"{b.base}/app.php/wiki/First%20article").text
ok(re.search(r'<a class="wikilink" href="[^"]*/wiki/Second%20article[^"]*"', first),
"[[Second article]] links to the existing article")
ok(re.search(r'<a class="wikilink wikilink-new" href="[^"]*/wiki/Missing%20page[^"]*"[^>]*>this one</a>', first),
"[[Missing page|this one]] shows its own text and is marked as a new article")
second = admin.get(f"{b.base}/app.php/wiki/Second%20article").text
ok("What links here" in second and re.search(r'href="[^"]*/wiki/First%20article[^"]*">First article</a>', second),
"Second article lists First article under What links here")
ok("What links here" not in first, "an article nothing links to has no What links here list")
topic = admin.get(f"{b.base}/viewtopic.php?t=1").text
ok(re.search(r'<a class="wikilink" href="[^"]*/wiki/Second%20article', topic),
"[[ ]] in a forum post links to the wiki article")
ok("[[Not a link]]" in topic, "[[ ]] inside a code block stays plain text")
posting = admin.get(f"{b.base}/posting.php?mode=reply&t=1&sid={sid}").text
ok("bbcode-wikilink" in posting, "the posting editor has the wiki link button")


def check_documentation(b: Board) -> None:
# The default build location moved over time (ext/.../docs-build, then
# store/phpbbmodders_documentation), so write the probe build wherever
Expand Down Expand Up @@ -321,6 +364,7 @@ def check_sfscompanion(b: Board) -> None:

CHECKS = {
"phpbbmodders/useridviewtopic": check_useridviewtopic,
"phpbbmodders/wiki": check_wiki,
"phpbbmodders/banlist": check_banlist,
"phpbbmodders/bannerrotator": check_bannerrotator,
"phpbbmodders/groupwarn": check_groupwarn,
Expand Down
81 changes: 79 additions & 2 deletions phpbb-test-board/screenshots.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
Exit status: 0 if every screenshot was saved, 1 if any failed, 2 for bad arguments.
"""
import argparse
import json
import shutil
import subprocess
import sys
Expand Down Expand Up @@ -65,13 +66,14 @@ def admin_sid(self) -> str:
return self._admin_sid

def shot(self, name: str, url: str, admin: bool = False, phone: bool = False,
selector: str = "", prepare: Callable = None) -> None:
selector: str = "", prepare: Callable = None, full_page: bool = False) -> None:
"""Save one screenshot as OUT_DIR/NAME.png.

url is relative to the board root. With admin=True the admin's session
is used and {sid} in url is replaced by its session id. selector crops
the image to that element; prepare(page) runs before the capture, for
example to open a tab or wait for results loaded by JavaScript.
full_page captures the whole page instead of the visible window.
"""
if admin:
url = url.replace("{sid}", self.admin_sid())
Expand All @@ -94,7 +96,7 @@ def shot(self, name: str, url: str, admin: bool = False, phone: bool = False,
if selector:
page.locator(selector).first.screenshot(path=str(target))
else:
page.screenshot(path=str(target))
page.screenshot(path=str(target), full_page=full_page)
self.saved.append(target)
print(f" [ok] {target.name}")
except (PlaywrightError, RuntimeError) as e:
Expand Down Expand Up @@ -167,6 +169,80 @@ def shots_prominodeux(board: Board, shoot: Shooter, args: argparse.Namespace) ->
shoot.shot("prominodeux-viewtopic-phone", f"viewtopic.php?t={topic}", phone=True)


def shots_wiki(board: Board, shoot: Shooter, args: argparse.Namespace) -> None:
"""phpbbmodders/wiki: overview, articles, editing, approval and links between articles."""
def add_article(title: str, text: str, description: str = "", views: int = 0, sticky: int = 0,
approved: int = 1, days_ago: float = 0, edit_reason: str = "") -> int:
"""Store one article version through phpBB's own text parser; return its id."""
out = board.php(
"$t = " + json.dumps(text) + "; $uid = $bit = ''; $flags = 0;"
"generate_text_for_storage($t, $uid, $bit, $flags, true, true, true);"
"$when = time() - " + str(int(days_ago * 86400)) + ";"
"$db->sql_query('INSERT INTO ' . $table_prefix . 'wiki_article ' . "
"$db->sql_build_array('INSERT', ['article_title' => " + json.dumps(title) + ", 'article_url' => "
+ json.dumps(title) + ", 'article_text' => $t, 'bbcode_uid' => $uid, 'bbcode_bitfield' => $bit, "
"'article_approved' => " + str(approved) + ", 'article_user_id' => 2, 'article_last_edit' => $when, "
"'article_time_created' => $when, 'article_sources' => '', 'article_description' => "
+ json.dumps(description) + ", 'article_views' => " + str(views) + ", 'article_sticky' => "
+ str(sticky) + ", 'article_edit_reason' => " + json.dumps(edit_reason) + "]));"
"echo $db->sql_nextid();",
check=True)
return int(out.strip().splitlines()[-1])

add_article("Getting Started",
"Welcome to the community wiki. Anyone can read it, and members can help keep it up to date."
"\n\n[b]Where to begin[/b]\n[list]\n[*]New to the board? Read the [[Frequently Asked Questions]]."
"\n[*]Installing the software yourself? Start with [[Installation]].\n[*]Writing posts? The "
"[[Formatting Guide]] covers bold text, lists, links and code.\n[/list]\n\nEvery edit is kept, "
"so nothing is lost: open [i]Versions[/i] on any article to see who changed what.",
"A quick tour of the board and the wiki.", views=148, sticky=1, days_ago=12)
add_article("Installation",
"Before you start, read the [[Requirements]]. Then follow [[Upgrading]] if you already run an "
"older version, or see the [[Troubleshooting|troubleshooting tips]] if something goes wrong."
"\n\nOnce installed, the [[Configuration]] page explains every setting.",
"Installing the software step by step.", views=96, days_ago=9)
add_article("Requirements", "You need phpBB 3.3 and PHP 7.4 or later. See [[Installation]] for the next steps.",
"What your server needs.", views=64, days_ago=8)
add_article("Configuration", "Every setting is described here. Return to [[Installation]].",
"Every setting explained.", views=51, days_ago=6)
add_article("Frequently Asked Questions",
"[b]How do I change my avatar?[/b]\nOpen the User Control Panel and choose Profile.",
"Common questions from new members.", views=23, days_ago=4)
guide = ("Use [b]bold[/b] for emphasis, [i]italic[/i] for titles and [code]code[/code] for code."
"\n\nSee the [[Getting Started]] page for more help.")
active = add_article("Formatting Guide", guide, "How to format posts with BBCode.", views=37, days_ago=3)
pending = add_article("Formatting Guide",
guide + "\n\nTo quote another post, click [i]Quote[/i] below it.",
"How to format posts with BBCode.", views=37, approved=0, days_ago=0.1,
edit_reason="Added a note about quoting")
board.purge_cache()

shoot.shot("wiki-overview", "app.php/wiki/?sid={sid}", admin=True, full_page=True)
shoot.shot("wiki-article-view", "app.php/wiki/Getting%20Started?sid={sid}", admin=True)
shoot.shot("wiki-edit", "app.php/wiki/Getting%20Started?action=edit&sid={sid}", admin=True, full_page=True)
# The first list on the overview is the pending one, shown to moderators.
shoot.shot("wiki-pending-articles", "app.php/wiki/?sid={sid}", admin=True, selector=".forumbg")
shoot.shot("wiki-compare", f"app.php/wiki/Formatting%20Guide?action=compare&from={pending}&to={active}"
"&sid={sid}", admin=True)

def open_moderator_controls(p) -> None:
p.click("#quickmod .dropdown-trigger")
p.wait_for_selector("#quickmod .dropdown:visible")
shoot.shot("wiki-moderator-controls", "app.php/wiki/Formatting%20Guide?action=versions&sid={sid}",
admin=True, prepare=open_moderator_controls)

# Requirements is linked from Installation and links back, so its page
# shows both a link and the What links here list.
shoot.shot("wiki-article-links", "app.php/wiki/Installation?sid={sid}", admin=True,
selector=".panel.bg1")
shoot.shot("wiki-what-links-here", "app.php/wiki/Requirements?sid={sid}", admin=True)

def highlight_button(p) -> None:
p.add_style_tag(content=".bbcode-wikilink { outline: 3px solid #d31141; outline-offset: 2px; }")
shoot.shot("wiki-link-button", "app.php/wiki/Requirements?action=edit&sid={sid}", admin=True,
selector="#format-buttons", prepare=highlight_button)


# Made-up values for the StopForumSpam screenshots. Nothing is ever sent to
# stopforumspam.com: the pages shown only read the board's own data and logs.
SFS_EXAMPLE_API_KEY = "0123456789abcdef"
Expand Down Expand Up @@ -254,6 +330,7 @@ def highlight_link(p) -> None:
"phpbbmodders/documentation": shots_documentation,
"phpbbmodders/sfscompanion": shots_sfscompanion,
"phpbbmodders/stopforumspam": shots_stopforumspam,
"phpbbmodders/wiki": shots_wiki,
"ProMinoDeux": shots_prominodeux,
}

Expand Down
Loading