Compare commits

...
Author SHA1 Message Date
Veloman Yunkan 091e9370e9 Automatic wombatization in case of updated test data 2026-03-17 14:43:49 +04:00
Veloman Yunkan e8dcf14fad Testing of an inter-page link with a hash
Added testing of an internal inter-page link with a fragment component.

Existing references to entries in issues.html served as such links
(which is how the bug was noticed), however it is better to have
a dedicated row in the test matrix for such a case.
2026-03-17 14:43:49 +04:00
Veloman Yunkan 755da7c255 Testing of links on a dynamic page
Note that the test dynamic page uses assignment to innerHTML (the method
of DOM manipulation is important in the context of interaction with
wombat.js which may not fully and correctly handle all the possible ways
in which dynamic content may appear).
2026-03-17 14:43:49 +04:00
Veloman Yunkan cb15d155f6 Added testing results for wombatized pages 2026-03-17 14:43:49 +04:00
Veloman Yunkan 75f98b88ef Wombatization of test pages
Added a script for wombatization of test pages
2026-03-17 14:43:49 +04:00
Veloman Yunkan db423a5ba9 Added a nested iframe test page
Also added a column to the test matrix table corresponding to this
additional dimension of testing.
2026-03-17 14:43:49 +04:00
Veloman Yunkan 75e34fa6e2 Enter test data for viewer testing
Added test data for centralized manual testing of various corner cases
of the kiwix-serve frontend.
2026-03-17 14:43:49 +04:00
16 changed files with 627 additions and 0 deletions

No files matched your search

+3
View File
@@ -0,0 +1,3 @@
content/plain/dyntest.html
content/wombatized
content/_zim_static
+27
View File
@@ -0,0 +1,27 @@
# Step 1:
Start `kiwix-serve` as follows (the `run` script can be executed from any
directory, the path to `kiwix-serve` must be specified relative to the current
working directory):
```
./run path/to/kiwix-serve
```
or
```
./run path/to/kiwix-serve --blockexternal
```
# Step 2:
Open http://localhost:8080/viewer#viewer\_testing/main.html in your browser
and proceed to the test pages listed there.
Don't forget to test both with Firefox and Chromium/Chrome.
# Step 3:
Click the links and check that the result is as expected for the mode being
tested.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1011 B

@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Testing of link/URL handling by kiwix-serve viewer</title>
</head>
<body>
<ul>
<li><a href="plain/test.html">Static page</a></li>
<li><a href="plain/nestediframe.html">Static page inside an iframe</a></li>
<li><a href="plain/dyntest.html">Dynamic page</a></li>
<li>
<a href="wombatized/test.html">Wombatized static page</a>
</li>
<li>
<a href="wombatized/nestediframe.html">
Wombatized static page inside an iframe
</a>
</li>
<li>
<a href="wombatized/dyntest.html">
Wombatized dynamic page
</a>
</li>
</ul>
</body>
</html>
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>This is another page in the same ZIM file</title>
</head>
<body>
This is another page in the same ZIM file
</body>
</html>
@@ -0,0 +1,69 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Issues of link/URL handling by kiwix-serve viewer</title>
<style>
:target {
background-color: yellow;
}
</style>
</head>
<body>
<h1>List of issues</h1>
<h2><a name="1-circumvention-via-forced-new-tab">Issue#1</a></h2>
<p>
Link blocking can be circumvented by forcing the link to be opened in a new
tab via middle-click or context menu.
</p>
<h2><a name="2-firefox-csp-error">Issue#2</a></h2>
<p>
Firefox: Link click has no effect, Content-Security-Policy error reported
in console.
</p>
<h2><a name="3-chromium-csp-error">Issue#3</a></h2>
<p>
Chromium: Blocked content error is displayed in the viewer.
</p>
<h2><a name="4-link-not-blocked">Issue#4</a></h2>
<p>
Link is not blocked.
</p>
<h2><a name="5-firefox-cross-origin-errors-in-console">Issue#5</a></h2>
<p>
Firefox: Errors in console: "DOMException: Permission denied to get property
"href" on cross-origin object".
</p>
<h2><a name="6-link-loads-in-iframe">Issue#6</a></h2>
<p>
If the link is inside an iframe, it loads inside the nested frame.
</p>
<h2><a name="7-new-tab-escapes-viewer">Issue#7</a></h2>
<p>
If the link is opened in a new tab, it breaks free from viewer.
</p>
<h2><a name="8-nested-iframe-circumvents-link-blocking">Issue#8</a></h2>
<p>
Links residing in a nested iframe avoid external link blocking
</p>
<h2><a name="9-url-not-found">Issue#9</a></h2>
<p>
A URL not found error is reported for /content/viewer_testing/example.com/.
</p>
<h2><a name="10-wombatjs-drops-fragments-of-dynamically-created-links">Issue#10</a></h2>
<p>
<code>wombat.js</code> drops the fragment component of dynamically created
links (at least those introduced by assigning to the <code>innerHTML</code>
attribute of an existing DOM element).
</p>
</body>
</html>
Binary file not shown.
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Testing of link/URL handling by kiwix-serve viewer</title>
</head>
<body>
<h1>Links Inside a Frame</h1>
<iframe src="test.html" width=90% height=800><iframe/>
</body>
</html>
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Another page in the same ZIM file</title>
<style>
:target {
background-color: yellow;
}
</style>
</head>
<body>
<h1>Another page in the same ZIM file</h1>
<p id="special-note">
If this paragraph is not highlighted then the fragment component of the link
has been lost.
</p>
</body>
</html>
@@ -0,0 +1,296 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Testing of link/URL handling by kiwix-serve viewer</title>
<style>
table {
border-collapse: collapse;
border: 2px solid rgb(140 140 140);
letter-spacing: 1px;
}
thead {
background-color: rgb(228 240 245);
}
th,
td {
border: 1px solid rgb(160 160 160);
padding: 8px 10px;
}
td {
width: 100px;
}
td {
text-align: center;
}
tbody > tr:nth-of-type(odd) {
background-color: rgb(237 238 242);
}
:target {
background-color: yellow;
}
</style>
</head>
<body>
<h1><a name='guidelines'>Testing Guidelines</a></h1>
<ul>
<li>Test in different browsers (Firefox, Chromium, desktop, mobile).</li>
<li>Test with external link blocking disabled/enabled.</li>
<li>Links activation can be performed by
<ul>
<li>clicking</li>
<li>CTRL clicking</li>
<li>SHIFT clicking</li>
<li>middle clicking</li>
<li>selecting "Open Link in New Tab" from the context menu</li>
<li>selecting "Copy Link" from the context menu</li>
</ul>
</li>
</ul>
<h1>Testing Status</h1>
<p>
In the tables below the <b>Base case</b> column represents the simplest setup
of the test page (no external link blocking, no wrapping iframe, etc). Each
subsequent column contains a list of (additional) problems observed for the
respective feature enabled (possibly in combination with one or more of the
features from the previous columns).
</p>
<p>
Issues referenced in the header of the column apply to the entire column or
most of its rows.
</p>
<h2>External links</h2>
<p>
Requirements:
<ul>
<li>
The viewer must NOT stay around after the link is followed (even if
intercepted by the link blocking page).
</li>
</ul>
</p>
<table>
<thead>
<tr>
<th colspan=2></th>
<th>Base case</th>
<th>External link blocking</th>
<th>
Nested iframe (<a href="issues.html#8-nested-iframe-circumvents-link-blocking">8</a>)
</th>
<th>Dynamic page</th>
<th>Wombatization</th>
</tr>
</thead>
<tr>
<th rowspan=2>External page</th>
<td><a href="https://example.com">Same tab</a></td>
<!--Base case --><td>&#9989;</td>
<!--Link blocking on -->
<td>
<a href="issues.html#1-circumvention-via-forced-new-tab">1</a>
</td>
<!--Nested iframe -->
<td>
<a href="issues.html#6-link-loads-in-iframe">6</a>
</td>
<!--Dynamic page --><td></td>
<!--Wombatization --><td></td>
</tr>
<tr>
<td><a href="https://example.com" target="_blank">New tab</a></td>
<!--Base case --><td>&#9989;</td>
<!--Link blocking on -->
<td>
<a href="issues.html#1-circumvention-via-forced-new-tab">1</a>
</td>
<!--Nested iframe --><td></td>
<!--Dynamic page --><td></td>
<!--Wombatization --><td></td>
</tr>
<tr>
<th rowspan=2>External page (JS link)</th>
<td><a href="javascript:window.open('https://example.com', '_self')">Same tab</a></td>
<!--Base case -->
<td>
<a href="issues.html#2-firefox-csp-error">2</a>
<a href="issues.html#3-chromium-csp-error">3</a>
</td>
<!--Link blocking on --><td></td>
<!--Nested iframe -->
<td>
<a href="issues.html#6-link-loads-in-iframe">6</a>
</td>
<!--Dynamic page --><td></td>
<!--Wombatization -->
<td>
<a href="issues.html#9-url-not-found">9</a>
</td>
</tr>
<tr>
<td><a href="javascript:window.open('https://example.com', '_blank')">New tab</a></td>
<!--Base case --><td>&#9989;</td>
<!--Link blocking on -->
<td>
<a href="issues.html#1-circumvention-via-forced-new-tab">1</a>
<a href="issues.html#4-link-not-blocked">4</a>
</td>
<!--Nested iframe --><td></td>
<!--Dynamic page --><td></td>
<!--Wombatization -->
<td>
<a href="issues.html#9-url-not-found">9</a>
</td>
</tr>
<tr>
<th rowspan=2>E-mail link</th>
<td><a href="mailto:someone@example.com">Same tab</a></td>
<!--Base case --><td>&#9989;</td>
<!--Link blocking on -->
<td>
<a href="issues.html#1-circumvention-via-forced-new-tab">1</a>
</td>
<!--Nested iframe --><td></td>
<!--Dynamic page --><td></td>
<!--Wombatization --><td></td>
</tr>
<tr>
<td><a href="mailto:someone@example.com" target="_blank">New tab</a></td>
<!--Base case --><td>&#9989;</td>
<!--Link blocking on -->
<td>
<a href="issues.html#1-circumvention-via-forced-new-tab">1</a>
</td>
<!--Nested iframe --><td></td>
<!--Dynamic page --><td></td>
<!--Wombatization --><td></td>
</tr>
</table>
<h2>Internal links</h2>
<p>
Requirements:
<ul>
<li>
When the link is opened in a new tab/window, the viewer must stay
around.
</li>
</ul>
</p>
<table>
<thead>
<tr>
<th colspan=2></th>
<th>Base case</th>
<th>External link blocking</th>
<th>
Nested iframe (<a href="issues.html#7-new-tab-escapes-viewer">7</a>)
</th>
<th>
Dynamic page (<a href="issues.html#7-new-tab-escapes-viewer">7</a>)
</th>
<th>
Wombatization (<a href="issues.html#7-new-tab-escapes-viewer">7</a>)
</th>
</tr>
</thead>
<tr>
<th rowspan=2>Intrapage</th>
<td><a href="#guidelines">Same tab</a></td>
<!--Base case --><td>&#9989;</td>
<!--Link blocking on --><td>&#9989;</td>
<!--Nested iframe --><td></td>
<!--Dynamic page --><td></td>
<!--Wombatization --><td></td>
</tr>
<tr>
<td><a href="#guidelines" target="_blank">New tab</a></td>
<!--Base case --><td>&#9989;</td>
<!--Link blocking on --><td>&#9989;</td>
<!--Nested iframe --><td></td>
<!--Dynamic page --><td></td>
<!--Wombatization --><td></td>
</tr>
<tr>
<th rowspan=2>HTML</th>
<td><a href="anotherpage.html">Same tab</a></td>
<!--Base case --><td>&#9989;</td>
<!--Link blocking on --><td>&#9989;</td>
<!--Nested iframe --><td></td>
<!--Dynamic page --><td></td>
<!--Wombatization --><td></td>
</tr>
<tr>
<td><a href="anotherpage.html" target="_blank">New tab</a></td>
<!--Base case --><td>&#9989;</td>
<!--Link blocking on --><td>&#9989;</td>
<!--Nested iframe --><td></td>
<!--Dynamic page --><td></td>
<!--Wombatization --><td></td>
</tr>
<tr>
<th rowspan=2>HTML (with a fragment)</th>
<td><a href="target_page_for_a_hash_link.html#special-note">Same tab</a></td>
<!--Base case --><td>&#9989;</td>
<!--Link blocking on --><td>&#9989;</td>
<!--Nested iframe --><td></td>
<!--Dynamic page --><td></td>
<!--Wombatization -->
<td>
<a href="issues.html#10-wombatjs-drops-fragments-of-dynamically-created-links">10</a>
</td>
</tr>
<tr>
<td><a href="target_page_for_a_hash_link.html#special-note" target="_blank">New tab</a></td>
<!--Base case --><td>&#9989;</td>
<!--Link blocking on --><td>&#9989;</td>
<!--Nested iframe --><td></td>
<!--Dynamic page --><td></td>
<!--Wombatization -->
<td>
<a href="issues.html#10-wombatjs-drops-fragments-of-dynamically-created-links">10</a>
</td>
</tr>
<tr>
<th rowspan=2>PDF</th>
<td><a href="./kiwix.pdf">Same tab</a></td>
<!--Base case -->
<td>
<a href="issues.html#5-firefox-cross-origin-errors-in-console">5</a>
</td>
<!--Link blocking on --><td></td>
<!--Nested iframe --><td></td>
<!--Dynamic page --><td></td>
<!--Wombatization --><td></td>
</tr>
<tr>
<td><a href="./kiwix.pdf" target="_blank">New tab</a></td>
<!--Base case -->
<td>
<a href="issues.html#5-firefox-cross-origin-errors-in-console">5</a>
</td>
<!--Link blocking on --><td></td>
<!--Nested iframe --><td></td>
<!--Dynamic page --><td></td>
<!--Wombatization --><td></td>
</tr>
</table>
</body>
</html>
+33
View File
@@ -0,0 +1,33 @@
#!/usr/bin/env bash
mydir=$(dirname "$0")
cd "$mydir"
infile=content/plain/test.html
outfile=content/plain/dyntest.html
sed -ne '1,/<body>/ p' "$infile" > "$outfile"
cat >> "$outfile" <<'END'
Patience! Content will appear in <span id=countdown>2</span> seconds.
</body>
<script>
const bodyHtmlStr = `
END
sed -e '1,/<body>/ d; /<\/body>/,$ d' "$infile" >> "$outfile"
cat >> "$outfile" <<'END'
`;
function update() {
const countdown = document.getElementById('countdown');
const countdownVal = +countdown.innerHTML;
if ( countdownVal > 0 ) {
countdown.innerHTML = countdownVal - 1;
setTimeout(update, 1000);
} else {
document.getElementsByTagName('body')[0].innerHTML = bodyHtmlStr;
}
}
setTimeout(update, 1000);
</script>
</html>
END
@@ -0,0 +1,18 @@
/content/viewer_testing/main.html text/html content/main.html
/content/viewer_testing/plain/nestediframe.html text/html content/plain/nestediframe.html
/content/viewer_testing/plain/test.html text/html content/plain/test.html
/content/viewer_testing/plain/dyntest.html text/html content/plain/dyntest.html
/content/viewer_testing/plain/anotherpage.html text/html content/plain/anotherpage.html
/content/viewer_testing/plain/target_page_for_a_hash_link.html text/html content/plain/target_page_for_a_hash_link.html
/content/viewer_testing/plain/issues.html text/html content/plain/issues.html
/content/viewer_testing/plain/kiwix.pdf application/pdf content/plain/kiwix.pdf
/content/viewer_testing/wombatized/nestediframe.html text/html content/wombatized/nestediframe.html
/content/viewer_testing/wombatized/test.html text/html content/wombatized/test.html
/content/viewer_testing/wombatized/dyntest.html text/html content/wombatized/dyntest.html
/content/viewer_testing/wombatized/anotherpage.html text/html content/wombatized/anotherpage.html
/content/viewer_testing/wombatized/target_page_for_a_hash_link.html text/html content/wombatized/target_page_for_a_hash_link.html
/content/viewer_testing/wombatized/issues.html text/html content/wombatized/issues.html
/content/viewer_testing/wombatized/kiwix.pdf application/pdf content/wombatized/kiwix.pdf
/content/viewer_testing/_zim_static/wombat.js application/javascript content/_zim_static/wombat.js
/content/viewer_testing/_zim_static/wombatSetup.js application/javascript content/_zim_static/wombatSetup.js
/raw/viewer_testing/meta/Title text/plain meta/Title
+2
View File
@@ -0,0 +1,2 @@
<library version="20110515">
</library>
+1
View File
@@ -0,0 +1 @@
Test content for kiwix-serve viewer
+56
View File
@@ -0,0 +1,56 @@
#!/usr/bin/env bash
if [ $# -eq 0 ]
then
echo >&2 "Usage: $0 path-to-kiwix-serve [options ...]"
exit 1
fi
kiwixserve=$(readlink -f "$1")
shift
set -x
mydir=$(dirname "$0")
cd "$mydir"
if [ content/plain/test.html -nt content/plain/dyntest.html ]
then
./generate_dynamic_page
fi
must_wombatize()
{
if [ ! -d content/wombatized ]
then
return 0
fi
if [ ! -d content/_zim_static ]
then
return 0
fi
for f in content/plain/*
do
if [ "$f" -nt "${f/plain/wombatized}" ]
then
return 0
fi
done
return 1
}
if must_wombatize
then
echo "Generating wombatized pages..."
if ! ./wombatize
then
echo "Encountered errors while generating wombatized pages. Exiting..."
exit 1
fi
echo "Successfully generated wombatized pages."
fi
export KIWIX_SERVE_CUSTOMIZED_RESOURCES=kiwix_serve_customized_resources
"$kiwixserve" -p 8080 --library "$@" library.xml
+54
View File
@@ -0,0 +1,54 @@
#!/usr/bin/env bash
mydir=$(dirname "$0")
die()
{
echo >&2 "ERROR: $@"
exit 1
}
if ! zimdump --version
then
die "No zimdump in the PATH"
fi
cd "$mydir"
rm -rf content/{_zim_static,wombatized}
pids_to_kill=()
set -ex
cleanup()
{
kill "${pids_to_kill[@]}"
wait
}
python3 -m http.server -d content/plain 8080 &
pids_to_kill+=($!)
trap cleanup EXIT
ip=$(docker network inspect bridge|jq '.[0].IPAM.Config|.[0].Gateway')
ip=${ip#\"}
ip=${ip%\"}
mkdir zimit_output
docker run --rm \
--volume "$(pwd)"/zimit_output:/output \
--add-host=wombatized:"$ip" \
ghcr.io/openzim/zimit:3.1.2 \
zimit --name="temp" \
--zim-file="temp.zim" \
--seeds="http://wombatized:8080/nestediframe.html,http://wombatized:8080/dyntest.html" \
--title="Temp" \
--description="Temp" \
#--favicon="https://wiki.kiwix.org/w/images/favicon.ico"
zimdump dump --dir content/ zimit_output/temp.zim
docker run --rm \
--volume "$(pwd)"/zimit_output:/output \
ghcr.io/openzim/zimit:3.1.2 \
bash -c "rm -vrf /output/*"
rmdir zimit_output