@internetarchive/bookreader 5.0.0-37 → 5.0.0-38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/node.js.yml +66 -4
- package/BookReader/BookReader.js +1 -1
- package/BookReader/ia-bookreader-bundle.js +1 -1
- package/BookReader/ia-bookreader-bundle.js.map +1 -1
- package/BookReader/plugins/plugin.search.js +1 -1
- package/BookReader/plugins/plugin.search.js.map +1 -1
- package/BookReader/plugins/plugin.tts.js +1 -1
- package/BookReader/plugins/plugin.tts.js.map +1 -1
- package/CHANGELOG.md +12 -0
- package/codecov.yml +6 -0
- package/package.json +12 -12
- package/renovate.json +43 -0
- package/src/plugins/search/plugin.search.js +5 -15
- package/src/plugins/search/view.js +2 -0
- package/src/plugins/tts/AbstractTTSEngine.js +9 -4
- package/stat/BookNavigator/BookNavigator.js +42 -0
- package/tests/e2e/base.test.js +4 -5
- package/tests/e2e/helpers/desktopSearch.js +13 -12
- package/tests/e2e/models/Navigation.js +12 -3
- package/tests/e2e/rightToLeft.test.js +1 -1
- package/tests/e2e/viewmode.test.js +37 -31
- package/.github/dependabot.yml +0 -8
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
# 5.0.0-38
|
2
|
+
Dev: Add Renovate Bot @cdrini
|
3
|
+
Dev: Update node-fetch @cdrini
|
4
|
+
Fix: Search request promise err & fix tests @cdrini
|
5
|
+
Dev: Split node workflow into different jobs @cdrini
|
6
|
+
Dev: Give cache steps better names in GHA @cdrini
|
7
|
+
Dev: Update concurrently + Small speedup to build & test @cdrini
|
8
|
+
Dev: Renovate - Auto-update dev dependencies for minor/patch @cdrini
|
9
|
+
Fix: Better MS Edge voice selection @cdrini
|
10
|
+
Dev: Allow small drops in codecov coverage (< 0.5%) @cdrini
|
11
|
+
Dev: Renovate - add `^@internetarchive/icon-` @cdrini
|
12
|
+
|
1
13
|
# 5.0.0-37
|
2
14
|
Fix: Update all `.then()` to async/await @sancodes
|
3
15
|
Fix: Upgrade to Lit 2 @Aadilhassan
|
package/codecov.yml
CHANGED
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@internetarchive/bookreader",
|
3
|
-
"version": "5.0.0-
|
3
|
+
"version": "5.0.0-38",
|
4
4
|
"description": "The Internet Archive BookReader.",
|
5
5
|
"repository": {
|
6
6
|
"type": "git",
|
@@ -41,25 +41,25 @@
|
|
41
41
|
"lit": "^2.1.3"
|
42
42
|
},
|
43
43
|
"devDependencies": {
|
44
|
-
"@babel/core": "7.
|
45
|
-
"@babel/eslint-parser": "
|
46
|
-
"@babel/plugin-proposal-class-properties": "
|
47
|
-
"@babel/plugin-proposal-decorators": "
|
48
|
-
"@babel/preset-env": "7.
|
44
|
+
"@babel/core": "7.17.5",
|
45
|
+
"@babel/eslint-parser": "7.17.0",
|
46
|
+
"@babel/plugin-proposal-class-properties": "7.16.7",
|
47
|
+
"@babel/plugin-proposal-decorators": "7.17.2",
|
48
|
+
"@babel/preset-env": "7.16.11",
|
49
49
|
"@open-wc/testing": "^3.0.4",
|
50
50
|
"@open-wc/testing-karma": "^4.0.9",
|
51
51
|
"@types/jest": "^27.4.0",
|
52
52
|
"@webcomponents/webcomponentsjs": "^2.6.0",
|
53
|
-
"babel-loader": "8.2.
|
53
|
+
"babel-loader": "8.2.3",
|
54
54
|
"codecov": "^3.8.3",
|
55
|
-
"concurrently": "
|
55
|
+
"concurrently": "7.0.0",
|
56
56
|
"core-js": "3.16.2",
|
57
57
|
"cpx2": "3.0.0",
|
58
58
|
"eslint": "^7.32.0",
|
59
59
|
"eslint-plugin-no-jquery": "^2.7.0",
|
60
60
|
"eslint-plugin-testcafe": "^0.2.1",
|
61
61
|
"hammerjs": "^2.0.8",
|
62
|
-
"http-server": "
|
62
|
+
"http-server": "14.1.0",
|
63
63
|
"iso-language-codes": "1.1.0",
|
64
64
|
"jest": "^27.4.7",
|
65
65
|
"jquery": "1.11.3",
|
@@ -70,7 +70,7 @@
|
|
70
70
|
"jquery.mmenu": "5.6.5",
|
71
71
|
"karma-coverage": "^2.1.0",
|
72
72
|
"live-server": "1.2.1",
|
73
|
-
"node-fetch": "2.6.
|
73
|
+
"node-fetch": "2.6.7",
|
74
74
|
"regenerator-runtime": "0.13.9",
|
75
75
|
"sass": "1.38.2",
|
76
76
|
"sinon": "^12.0.1",
|
@@ -102,7 +102,7 @@
|
|
102
102
|
"preversion": "npm run test && node scripts/preversion.js",
|
103
103
|
"version": "node scripts/version.js",
|
104
104
|
"postversion": "node scripts/postversion.js",
|
105
|
-
"build": "npm run clean &&
|
105
|
+
"build": "npm run clean && npx concurrently --group npm:build-js npm:build-css npm:build-assets",
|
106
106
|
"build-assets": "npx cpx \"src/assets/**/*\" BookReader && npx svgo -f BookReader/icons && npx svgo -f BookReader/images",
|
107
107
|
"build-assets:watch": "npx cpx --watch --verbose \"src/assets/**/*\" BookReader",
|
108
108
|
"build-js": "npx webpack",
|
@@ -115,7 +115,7 @@
|
|
115
115
|
"serve": "npx http-server . --port 8000",
|
116
116
|
"serve-live": "npx live-server . --port 8000 --watch=index.html,BookReader,BookReaderDemo",
|
117
117
|
"serve-dev": "npm run build-css && npx concurrently --kill-others npm:serve-live npm:build-*:watch",
|
118
|
-
"test": "
|
118
|
+
"test": "npx concurrently --group npm:test-jest npm:test-karma",
|
119
119
|
"test:e2e": "npm run build && npx testcafe",
|
120
120
|
"test:e2e:dev": "npx testcafe --live --dev",
|
121
121
|
"test-jest:watch": "npx jest --watch",
|
package/renovate.json
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
{
|
2
|
+
"extends": [
|
3
|
+
"config:base"
|
4
|
+
],
|
5
|
+
"packageRules": [
|
6
|
+
{
|
7
|
+
"matchPackageNames": [
|
8
|
+
"@babel/eslint-parser",
|
9
|
+
"@open-wc/testing",
|
10
|
+
"@open-wc/testing-karma",
|
11
|
+
"@types/jest",
|
12
|
+
"codecov",
|
13
|
+
"eslint",
|
14
|
+
"eslint-plugin-no-jquery",
|
15
|
+
"eslint-plugin-testcafe",
|
16
|
+
"jest",
|
17
|
+
"karma-coverage",
|
18
|
+
"sinon",
|
19
|
+
"testcafe"
|
20
|
+
],
|
21
|
+
"automerge": true
|
22
|
+
},
|
23
|
+
{
|
24
|
+
"matchPackageNames": [
|
25
|
+
"concurrently",
|
26
|
+
"http-server",
|
27
|
+
"live-server",
|
28
|
+
"node-fetch"
|
29
|
+
],
|
30
|
+
"matchUpdateTypes": ["minor", "patch"],
|
31
|
+
"automerge": true
|
32
|
+
},
|
33
|
+
{
|
34
|
+
"matchPackagePatterns": ["^@internetarchive/icon-"],
|
35
|
+
"groupName": "@internetarchive icons",
|
36
|
+
"rangeStrategy": "bump"
|
37
|
+
},
|
38
|
+
{
|
39
|
+
"matchPackagePatterns": ["^@internetarchive"],
|
40
|
+
"rangeStrategy": "bump"
|
41
|
+
}
|
42
|
+
]
|
43
|
+
}
|
@@ -144,6 +144,7 @@ BookReader.prototype.search = async function(term = '', overrides = {}) {
|
|
144
144
|
};
|
145
145
|
const options = jQuery.extend({}, defaultOptions, overrides);
|
146
146
|
this.suppressFragmentChange = options.suppressFragmentChange;
|
147
|
+
this.searchCancelled = false;
|
147
148
|
|
148
149
|
// strip slashes, since this goes in the url
|
149
150
|
this.searchTerm = term.replace(/\//g, ' ');
|
@@ -179,13 +180,8 @@ BookReader.prototype.search = async function(term = '', overrides = {}) {
|
|
179
180
|
|
180
181
|
const url = `${baseUrl}${paramStr}`;
|
181
182
|
|
182
|
-
const cleanup = () => {
|
183
|
-
this.searchXHR = null;
|
184
|
-
window.BRSearchInProgress = () => {};
|
185
|
-
};
|
186
|
-
|
187
183
|
const processSearchResults = (searchInsideResults) => {
|
188
|
-
if (
|
184
|
+
if (this.searchCancelled) {
|
189
185
|
return;
|
190
186
|
}
|
191
187
|
const responseHasError = searchInsideResults.error || !searchInsideResults.matches.length;
|
@@ -201,12 +197,6 @@ BookReader.prototype.search = async function(term = '', overrides = {}) {
|
|
201
197
|
? options.success.call(this, searchInsideResults, options)
|
202
198
|
: this.BRSearchCallback(searchInsideResults, options);
|
203
199
|
}
|
204
|
-
cleanup();
|
205
|
-
};
|
206
|
-
|
207
|
-
const beforeSend = (xhr) => {
|
208
|
-
this.searchXHR = xhr;
|
209
|
-
window.BRSearchInProgress = processSearchResults;
|
210
200
|
};
|
211
201
|
|
212
202
|
this.trigger('SearchStarted', { term: this.searchTerm, instance: this });
|
@@ -214,8 +204,7 @@ BookReader.prototype.search = async function(term = '', overrides = {}) {
|
|
214
204
|
url: url,
|
215
205
|
dataType: 'jsonp',
|
216
206
|
cache: true,
|
217
|
-
beforeSend,
|
218
|
-
jsonpCallback: 'BRSearchInProgress'
|
207
|
+
beforeSend: xhr => { this.searchXHR = xhr; },
|
219
208
|
}));
|
220
209
|
};
|
221
210
|
|
@@ -228,8 +217,8 @@ BookReader.prototype._cancelSearch = function () {
|
|
228
217
|
this.searchView.clearSearchFieldAndResults(false);
|
229
218
|
this.searchTerm = '';
|
230
219
|
this.searchXHR = null;
|
220
|
+
this.searchCancelled = true;
|
231
221
|
this.searchResults = [];
|
232
|
-
window.BRSearchInProgress = () => {};
|
233
222
|
};
|
234
223
|
|
235
224
|
/**
|
@@ -237,6 +226,7 @@ BookReader.prototype._cancelSearch = function () {
|
|
237
226
|
* checks for term & xhr in flight before running
|
238
227
|
*/
|
239
228
|
BookReader.prototype.cancelSearchRequest = function () {
|
229
|
+
this.searchCancelled = true;
|
240
230
|
if (this.searchXHR !== null) {
|
241
231
|
this._cancelSearch();
|
242
232
|
this.searchView.toggleSearchPending();
|
@@ -149,10 +149,12 @@ class SearchView {
|
|
149
149
|
}
|
150
150
|
|
151
151
|
updateResultsPosition() {
|
152
|
+
if (!this.dom.searchNavigation) return;
|
152
153
|
this.dom.searchNavigation.find('[data-id=resultsCount]').text(this.resultsPosition());
|
153
154
|
}
|
154
155
|
|
155
156
|
updateSearchNavigationButtons() {
|
157
|
+
if (!this.dom.searchNavigation) return;
|
156
158
|
this.dom.searchNavigation.find('.prev').attr('disabled', !this.currentMatchIndex);
|
157
159
|
this.dom.searchNavigation.find('.next').attr('disabled', this.currentMatchIndex + 1 === this.matches.length);
|
158
160
|
}
|
@@ -51,9 +51,7 @@ export default class AbstractTTSEngine {
|
|
51
51
|
/** @type {SpeechSynthesisVoice} */
|
52
52
|
this.voice = null;
|
53
53
|
// Listen for voice changes (fired by subclasses)
|
54
|
-
this.events.on('voiceschanged',
|
55
|
-
this.voice = AbstractTTSEngine.getBestBookVoice(this.getVoices(), this.opts.bookLanguage);
|
56
|
-
});
|
54
|
+
this.events.on('voiceschanged', this.updateBestVoice);
|
57
55
|
this.events.trigger('voiceschanged');
|
58
56
|
}
|
59
57
|
|
@@ -72,6 +70,10 @@ export default class AbstractTTSEngine {
|
|
72
70
|
/** @abstract */
|
73
71
|
init() { return null; }
|
74
72
|
|
73
|
+
updateBestVoice = () => {
|
74
|
+
this.voice = AbstractTTSEngine.getBestBookVoice(this.getVoices(), this.opts.bookLanguage);
|
75
|
+
}
|
76
|
+
|
75
77
|
/**
|
76
78
|
* @param {number} leafIndex
|
77
79
|
* @param {number} numLeafs total number of leafs in the current book
|
@@ -134,8 +136,11 @@ export default class AbstractTTSEngine {
|
|
134
136
|
this.step();
|
135
137
|
}
|
136
138
|
|
137
|
-
/** @param {
|
139
|
+
/** @param {string} voiceURI */
|
138
140
|
setVoice(voiceURI) {
|
141
|
+
// if the user actively selects a voice, don't re-choose best voice anymore
|
142
|
+
// MS Edge fires voices changed randomly very often
|
143
|
+
this.events.off('voiceschanged', this.updateBestVoice);
|
139
144
|
this.voice = this.getVoices().find(voice => voice.voiceURI === voiceURI);
|
140
145
|
if (this.activeSound) this.activeSound.setVoice(this.voice);
|
141
146
|
}
|
@@ -1,3 +1,44 @@
|
|
1
|
+
/*
|
2
|
+
<script src="foo-plugin.js"></script>
|
3
|
+
|
4
|
+
foo-plugin.js
|
5
|
+
|
6
|
+
$('#foo-plugin').dataSet('MainController', 'bar');
|
7
|
+
|
8
|
+
<ia-bookreader>
|
9
|
+
<div slot="plugins">
|
10
|
+
<ia-search></ia-search>
|
11
|
+
<book-marks></book-marks>
|
12
|
+
</div>
|
13
|
+
</ia-bookreader>
|
14
|
+
|
15
|
+
iaBookreader.registerPlugin('foo-plugin', Class);
|
16
|
+
|
17
|
+
|
18
|
+
class IABr extends LItElement {
|
19
|
+
|
20
|
+
render() {
|
21
|
+
|
22
|
+
registerPlugins() {
|
23
|
+
this.pluginSlots.map(slot => {
|
24
|
+
.. to slot registry
|
25
|
+
each slot - do handshake
|
26
|
+
|
27
|
+
|
28
|
+
});
|
29
|
+
}
|
30
|
+
|
31
|
+
html`
|
32
|
+
<div slot="plugins" @onslotchange=${() => x}></div>
|
33
|
+
`;
|
34
|
+
}
|
35
|
+
}
|
36
|
+
*/
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
|
1
42
|
import { css, html, LitElement } from 'lit-element';
|
2
43
|
import { SharedResizeObserver } from '@internetarchive/shared-resize-observer';
|
3
44
|
import SearchProvider from './search/search-provider.js';
|
@@ -113,6 +154,7 @@ export class BookNavigator extends LitElement {
|
|
113
154
|
// };
|
114
155
|
|
115
156
|
this.menuProviders = {
|
157
|
+
// if enableSearch ?
|
116
158
|
search: new SearchProvider(
|
117
159
|
/**
|
118
160
|
* Search specific menu updates
|
package/tests/e2e/base.test.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import { runBaseTests } from './helpers/base';
|
2
2
|
import BookReader from './models/BookReader';
|
3
|
-
|
3
|
+
import { runDesktopSearchTests } from './helpers/desktopSearch';
|
4
4
|
// import { runMobileSearchTests } from './helpers/mobileSearch';
|
5
5
|
import params from './helpers/params';
|
6
6
|
|
@@ -22,10 +22,9 @@ ocaids.forEach(ocaid => {
|
|
22
22
|
runBaseTests(new BookReader());
|
23
23
|
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
// runDesktopSearchTests(new BookReader());
|
25
|
+
fixture `Desktop Search Tests for: ${ocaid}`
|
26
|
+
.page `${url}`;
|
27
|
+
runDesktopSearchTests(new BookReader());
|
29
28
|
|
30
29
|
// Todo: deprecated, will remove once mmenu is removed.
|
31
30
|
// fixture `Mobile Search Tests for: ${ocaid}`
|
@@ -19,14 +19,15 @@ export function runDesktopSearchTests(br) {
|
|
19
19
|
const nav = br.nav;
|
20
20
|
|
21
21
|
//assuring that the search bar is enabled
|
22
|
-
await t.expect(nav.desktop.
|
22
|
+
await t.expect(nav.desktop.searchIcon.visible).ok();
|
23
|
+
await t.click(nav.desktop.searchIcon);
|
23
24
|
|
24
25
|
//testing search for a word found in the book
|
25
|
-
await t
|
26
|
-
|
27
|
-
|
28
|
-
await t.
|
29
|
-
|
26
|
+
await t.selectText(nav.desktop.searchBox).pressKey('delete');
|
27
|
+
// FIXME: Why is it only typing every other letter?!?!
|
28
|
+
await t.typeText(nav.desktop.searchBox, TEST_TEXT_FOUND.split('').join('_'));
|
29
|
+
await t.pressKey('enter');
|
30
|
+
|
30
31
|
await t.expect(nav.desktop.searchPin.exists).ok();
|
31
32
|
await t.expect(nav.desktop.searchPin.child('.BRquery').child('div').exists).ok();
|
32
33
|
await t.expect(nav.desktop.searchPin.child('.BRquery').child('div').innerText).contains(TEST_TEXT_FOUND);
|
@@ -54,14 +55,14 @@ export function runDesktopSearchTests(br) {
|
|
54
55
|
const nav = br.nav;
|
55
56
|
|
56
57
|
//assuring that the search bar is enabled
|
57
|
-
await t.expect(nav.desktop.
|
58
|
+
await t.expect(nav.desktop.searchIcon.visible).ok();
|
59
|
+
await t.click(nav.desktop.searchIcon);
|
58
60
|
|
59
61
|
//testing search for a word not found in the book
|
60
|
-
await t
|
61
|
-
|
62
|
-
|
63
|
-
await t.
|
64
|
-
await t.click((nav.desktop.searchBox).child('.BRsearchSubmit'));
|
62
|
+
await t.selectText(nav.desktop.searchBox).pressKey('delete');
|
63
|
+
// FIXME: Why is it only typing every other letter?!?!
|
64
|
+
await t.typeText(nav.desktop.searchBox, TEST_TEXT_NOT_FOUND.split('').join('_'));
|
65
|
+
await t.pressKey('enter');
|
65
66
|
await t.expect(nav.desktop.searchPin.child('.BRquery').child('div').withText(TEST_TEXT_NOT_FOUND).exists).notOk();
|
66
67
|
|
67
68
|
const getPageUrl = ClientFunction(() => window.location.href.toString());
|
@@ -6,7 +6,8 @@ export default class Navigation {
|
|
6
6
|
this.topNavShell = new Selector('.BRtoolbar');
|
7
7
|
this.bottomNavShell = new Selector('.BRfooter');
|
8
8
|
this.mobileMenu = new Selector('.BRmobileMenu');
|
9
|
-
this.
|
9
|
+
this.itemNav = Selector('ia-bookreader').shadowRoot().find('ia-item-navigator').shadowRoot();
|
10
|
+
this.desktop = new DesktopNav(this.bottomNavShell, this.itemNav);
|
10
11
|
this.mobile = new MobileNav(this.mobileMenu, this.topNavShell);
|
11
12
|
}
|
12
13
|
}
|
@@ -17,7 +18,11 @@ export default class Navigation {
|
|
17
18
|
* @classdesc defines DesktopNav base elements
|
18
19
|
*/
|
19
20
|
class DesktopNav {
|
20
|
-
|
21
|
+
/**
|
22
|
+
* @param {Selector} bottomToolbar
|
23
|
+
* @param {Selector} itemNav
|
24
|
+
*/
|
25
|
+
constructor(bottomToolbar, itemNav) {
|
21
26
|
// flipping
|
22
27
|
this.goLeft = bottomToolbar.find('.BRicon.book_left');
|
23
28
|
this.goRight = bottomToolbar.find('.BRicon.book_right');
|
@@ -35,7 +40,11 @@ class DesktopNav {
|
|
35
40
|
this.zoomOut = bottomToolbar.find('.BRicon.zoom_out');
|
36
41
|
|
37
42
|
// search
|
38
|
-
this.
|
43
|
+
this.searchIcon = itemNav.find('button.shortcut.search');
|
44
|
+
this.searchBox = itemNav
|
45
|
+
.find('ia-menu-slider').shadowRoot()
|
46
|
+
.find('ia-book-search-results').shadowRoot()
|
47
|
+
.find('input[name=query]');
|
39
48
|
this.searchPin = bottomToolbar.find('.BRsearch');
|
40
49
|
this.searchNavigation = bottomToolbar.find('.BRsearch-navigation');
|
41
50
|
|
@@ -9,7 +9,7 @@ const ocaids = params.ocaids || [
|
|
9
9
|
];
|
10
10
|
|
11
11
|
ocaids.forEach(ocaid => {
|
12
|
-
const url = `${params.
|
12
|
+
const url = `${params.getArchiveUrl(ocaid)}`;
|
13
13
|
|
14
14
|
fixture `Base Tests for right to left book: ${ocaid}`.page `${url}`;
|
15
15
|
runBaseTests(new BookReader({ pageProgression: 'rl' }));
|
@@ -2,35 +2,41 @@ import { Selector } from 'testcafe';
|
|
2
2
|
import BookReader from './models/BookReader';
|
3
3
|
import params from './helpers/params';
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
const
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
5
|
+
const ocaids = params.ocaids || ['goody'];
|
6
|
+
|
7
|
+
ocaids.forEach(ocaid => {
|
8
|
+
const url = params.getArchiveUrl(ocaid);
|
9
|
+
|
10
|
+
fixture `Viewmode carousel`.page `${url}`;
|
11
|
+
|
12
|
+
test('Clicking `view mode` cycles through view modes', async t => {
|
13
|
+
const { nav } = (new BookReader());
|
14
|
+
|
15
|
+
// viewmode button only appear on mobile devices
|
16
|
+
await t.resizeWindow(400, 800);
|
17
|
+
// Flip forward one
|
18
|
+
await t.pressKey('right');
|
19
|
+
|
20
|
+
// 2up to thumb
|
21
|
+
await t.click(nav.desktop.viewmode);
|
22
|
+
const thumbnailContainer = Selector('.BRmodeThumb');
|
23
|
+
await t.expect(thumbnailContainer.visible).ok();
|
24
|
+
const thumbImages = thumbnailContainer.find('.BRpageview img');
|
25
|
+
await t.expect(thumbImages.count).gt(0);
|
26
|
+
|
27
|
+
// thumb to 1up
|
28
|
+
await t.click(nav.desktop.viewmode);
|
29
|
+
const onePageViewContainer = Selector('br-mode-1up');
|
30
|
+
await t.expect(onePageViewContainer.visible).ok();
|
31
|
+
const onePageImages = onePageViewContainer.find('.BRmode1up .BRpagecontainer');
|
32
|
+
// we usually pre-fetch the page in question & 1 before/after it
|
33
|
+
await t.expect(onePageImages.count).gte(3);
|
34
|
+
|
35
|
+
// 1up to 2up
|
36
|
+
await t.click(nav.desktop.viewmode);
|
37
|
+
const twoPageContainer = Selector('.BRtwopageview');
|
38
|
+
await t.expect(twoPageContainer.visible).ok();
|
39
|
+
const twoPageImages = twoPageContainer.find('img.BRpageimage');
|
40
|
+
await t.expect(twoPageImages.count).gte(2);
|
41
|
+
});
|
36
42
|
});
|