2022-07-01 20:19:57 +00:00
|
|
|
// @ts-ignore
|
|
|
|
window.matchMedia = window.matchMedia || function () {
|
|
|
|
return {
|
|
|
|
matches: false,
|
|
|
|
onchange: () => {}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2022-03-17 16:54:26 +00:00
|
|
|
const { test } = require( '../../../resources/skins.vector.es6/main.js' );
|
2022-05-31 22:32:50 +00:00
|
|
|
const {
|
|
|
|
STICKY_HEADER_EXPERIMENT_NAME,
|
|
|
|
STICKY_HEADER_EDIT_EXPERIMENT_NAME
|
|
|
|
} = require( '../../../resources/skins.vector.es6/stickyHeader.js' );
|
2022-03-17 16:54:26 +00:00
|
|
|
describe( 'main.js', () => {
|
|
|
|
it( 'getHeadingIntersectionHandler', () => {
|
|
|
|
const section = document.createElement( 'div' );
|
|
|
|
section.setAttribute( 'class', 'mw-body-content' );
|
|
|
|
section.setAttribute( 'id', 'mw-content-text' );
|
|
|
|
const heading = document.createElement( 'h2' );
|
|
|
|
const headline = document.createElement( 'span' );
|
|
|
|
headline.classList.add( 'mw-headline' );
|
|
|
|
headline.setAttribute( 'id', 'headline' );
|
|
|
|
heading.appendChild( headline );
|
|
|
|
section.appendChild(
|
|
|
|
heading
|
|
|
|
);
|
|
|
|
|
|
|
|
[
|
|
|
|
[ section, 'toc-mw-content-text' ],
|
|
|
|
[ heading, 'toc-headline' ]
|
|
|
|
].forEach( ( testCase ) => {
|
|
|
|
const node = /** @type {HTMLElement} */ ( testCase[ 0 ] );
|
|
|
|
const fn = jest.fn();
|
|
|
|
const handler = test.getHeadingIntersectionHandler( fn );
|
|
|
|
handler( node );
|
|
|
|
expect( fn ).toHaveBeenCalledWith( testCase[ 1 ] );
|
|
|
|
} );
|
|
|
|
} );
|
2022-05-31 22:32:50 +00:00
|
|
|
|
|
|
|
it( 'initStickyHeaderABTests', () => {
|
|
|
|
const STICKY_HEADER_AB = {
|
|
|
|
name: STICKY_HEADER_EXPERIMENT_NAME,
|
|
|
|
enabled: true
|
|
|
|
};
|
|
|
|
const STICKY_HEADER_AB_EDIT = {
|
|
|
|
name: STICKY_HEADER_EDIT_EXPERIMENT_NAME,
|
|
|
|
enabled: true
|
|
|
|
};
|
2022-06-15 22:01:02 +00:00
|
|
|
const DISABLED_STICKY_HEADER_AB_EDIT = {
|
|
|
|
name: STICKY_HEADER_EDIT_EXPERIMENT_NAME,
|
|
|
|
enabled: false
|
|
|
|
};
|
2022-05-31 22:32:50 +00:00
|
|
|
[
|
|
|
|
{
|
|
|
|
abConfig: STICKY_HEADER_AB_EDIT,
|
|
|
|
isEnabled: false,
|
|
|
|
isUserInTreatmentBucket: false,
|
|
|
|
expectedResult: {
|
|
|
|
showStickyHeader: false,
|
|
|
|
disableEditIcons: true
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
abConfig: STICKY_HEADER_AB_EDIT,
|
|
|
|
isEnabled: true,
|
|
|
|
isUserInTreatmentBucket: false,
|
|
|
|
expectedResult: {
|
Sticky header AB test bucketing for 2 treatment buckets
For idwiki/viwiki, we wish to run the sticky header edit button AB
test so that treatment1 group sees the sticky header without edit
buttons, treatment2 groups sees the sticky header with edit buttons,
and the control/unsampled groups see no sticky header at all.
This patch overrides the configuration to make the sticky header
w/o edit buttons for treatment1, sticky header w/ edit buttons for
treatment2, and hides sticky header for everyone else. This depends
on a configuration with the treatment groups having "treatment1"
and "treatment2" as substrings in their bucket names.
The full configuration for idwiki/viwiki would be something like
the following:
```
$wgVectorStickyHeader = [
"logged_in" => true,
"logged_out" => false,
];
$wgVectorStickyHeaderEdit = [
"logged_in" => true,
"logged_out" => false,
];
$wgVectorWebABTestEnrollment = [
"name" => "vector.sticky_header_edit",
"enabled" => true,
"buckets" => [
"unsampled" => [
"samplingRate" => 0
],
"noStickyHeaderControl" => [
"samplingRate" => 0.34
],
"stickyHeaderNoEditButtonTreatment1" => [
"samplingRate" => 0.33
],
"stickyHeaderEditButtonTreatment2" => [
"samplingRate" => 0.33
]
],
];
```
Bug: T312573
Change-Id: I15c360fdf5393f5594602acc33b5b916e904016d
2022-07-07 19:06:14 +00:00
|
|
|
showStickyHeader: false,
|
2022-05-31 22:32:50 +00:00
|
|
|
disableEditIcons: true
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
abConfig: STICKY_HEADER_AB_EDIT,
|
|
|
|
isEnabled: true,
|
|
|
|
isUserInTreatmentBucket: true,
|
|
|
|
expectedResult: {
|
|
|
|
showStickyHeader: true,
|
|
|
|
disableEditIcons: false
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
abConfig: STICKY_HEADER_AB,
|
|
|
|
isEnabled: false, // sticky header unavailable
|
Sticky header AB test bucketing for 2 treatment buckets
For idwiki/viwiki, we wish to run the sticky header edit button AB
test so that treatment1 group sees the sticky header without edit
buttons, treatment2 groups sees the sticky header with edit buttons,
and the control/unsampled groups see no sticky header at all.
This patch overrides the configuration to make the sticky header
w/o edit buttons for treatment1, sticky header w/ edit buttons for
treatment2, and hides sticky header for everyone else. This depends
on a configuration with the treatment groups having "treatment1"
and "treatment2" as substrings in their bucket names.
The full configuration for idwiki/viwiki would be something like
the following:
```
$wgVectorStickyHeader = [
"logged_in" => true,
"logged_out" => false,
];
$wgVectorStickyHeaderEdit = [
"logged_in" => true,
"logged_out" => false,
];
$wgVectorWebABTestEnrollment = [
"name" => "vector.sticky_header_edit",
"enabled" => true,
"buckets" => [
"unsampled" => [
"samplingRate" => 0
],
"noStickyHeaderControl" => [
"samplingRate" => 0.34
],
"stickyHeaderNoEditButtonTreatment1" => [
"samplingRate" => 0.33
],
"stickyHeaderEditButtonTreatment2" => [
"samplingRate" => 0.33
]
],
];
```
Bug: T312573
Change-Id: I15c360fdf5393f5594602acc33b5b916e904016d
2022-07-07 19:06:14 +00:00
|
|
|
isUserInTreatmentBucket: false, // not in treatment bucket
|
2022-05-31 22:32:50 +00:00
|
|
|
expectedResult: {
|
|
|
|
showStickyHeader: false,
|
|
|
|
disableEditIcons: true
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
abConfig: STICKY_HEADER_AB,
|
|
|
|
isEnabled: true, // sticky header available
|
Sticky header AB test bucketing for 2 treatment buckets
For idwiki/viwiki, we wish to run the sticky header edit button AB
test so that treatment1 group sees the sticky header without edit
buttons, treatment2 groups sees the sticky header with edit buttons,
and the control/unsampled groups see no sticky header at all.
This patch overrides the configuration to make the sticky header
w/o edit buttons for treatment1, sticky header w/ edit buttons for
treatment2, and hides sticky header for everyone else. This depends
on a configuration with the treatment groups having "treatment1"
and "treatment2" as substrings in their bucket names.
The full configuration for idwiki/viwiki would be something like
the following:
```
$wgVectorStickyHeader = [
"logged_in" => true,
"logged_out" => false,
];
$wgVectorStickyHeaderEdit = [
"logged_in" => true,
"logged_out" => false,
];
$wgVectorWebABTestEnrollment = [
"name" => "vector.sticky_header_edit",
"enabled" => true,
"buckets" => [
"unsampled" => [
"samplingRate" => 0
],
"noStickyHeaderControl" => [
"samplingRate" => 0.34
],
"stickyHeaderNoEditButtonTreatment1" => [
"samplingRate" => 0.33
],
"stickyHeaderEditButtonTreatment2" => [
"samplingRate" => 0.33
]
],
];
```
Bug: T312573
Change-Id: I15c360fdf5393f5594602acc33b5b916e904016d
2022-07-07 19:06:14 +00:00
|
|
|
isUserInTreatmentBucket: false, // not in treatment bucket
|
2022-05-31 22:32:50 +00:00
|
|
|
expectedResult: {
|
|
|
|
showStickyHeader: false,
|
|
|
|
disableEditIcons: true
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
abConfig: STICKY_HEADER_AB,
|
|
|
|
isEnabled: false, // sticky header is not available
|
Sticky header AB test bucketing for 2 treatment buckets
For idwiki/viwiki, we wish to run the sticky header edit button AB
test so that treatment1 group sees the sticky header without edit
buttons, treatment2 groups sees the sticky header with edit buttons,
and the control/unsampled groups see no sticky header at all.
This patch overrides the configuration to make the sticky header
w/o edit buttons for treatment1, sticky header w/ edit buttons for
treatment2, and hides sticky header for everyone else. This depends
on a configuration with the treatment groups having "treatment1"
and "treatment2" as substrings in their bucket names.
The full configuration for idwiki/viwiki would be something like
the following:
```
$wgVectorStickyHeader = [
"logged_in" => true,
"logged_out" => false,
];
$wgVectorStickyHeaderEdit = [
"logged_in" => true,
"logged_out" => false,
];
$wgVectorWebABTestEnrollment = [
"name" => "vector.sticky_header_edit",
"enabled" => true,
"buckets" => [
"unsampled" => [
"samplingRate" => 0
],
"noStickyHeaderControl" => [
"samplingRate" => 0.34
],
"stickyHeaderNoEditButtonTreatment1" => [
"samplingRate" => 0.33
],
"stickyHeaderEditButtonTreatment2" => [
"samplingRate" => 0.33
]
],
];
```
Bug: T312573
Change-Id: I15c360fdf5393f5594602acc33b5b916e904016d
2022-07-07 19:06:14 +00:00
|
|
|
isUserInTreatmentBucket: true, // but the user is in the treatment bucket
|
2022-05-31 22:32:50 +00:00
|
|
|
expectedResult: {
|
|
|
|
showStickyHeader: false,
|
|
|
|
disableEditIcons: true
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
abConfig: STICKY_HEADER_AB,
|
|
|
|
isEnabled: true,
|
|
|
|
isUserInTreatmentBucket: true,
|
|
|
|
expectedResult: {
|
|
|
|
showStickyHeader: true,
|
|
|
|
disableEditIcons: true
|
|
|
|
}
|
2022-06-15 22:01:02 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
abConfig: DISABLED_STICKY_HEADER_AB_EDIT,
|
|
|
|
isEnabled: true,
|
|
|
|
isUserInTreatmentBucket: false,
|
|
|
|
expectedResult: {
|
|
|
|
showStickyHeader: true,
|
|
|
|
disableEditIcons: false
|
|
|
|
}
|
2022-05-31 22:32:50 +00:00
|
|
|
}
|
Sticky header AB test bucketing for 2 treatment buckets
For idwiki/viwiki, we wish to run the sticky header edit button AB
test so that treatment1 group sees the sticky header without edit
buttons, treatment2 groups sees the sticky header with edit buttons,
and the control/unsampled groups see no sticky header at all.
This patch overrides the configuration to make the sticky header
w/o edit buttons for treatment1, sticky header w/ edit buttons for
treatment2, and hides sticky header for everyone else. This depends
on a configuration with the treatment groups having "treatment1"
and "treatment2" as substrings in their bucket names.
The full configuration for idwiki/viwiki would be something like
the following:
```
$wgVectorStickyHeader = [
"logged_in" => true,
"logged_out" => false,
];
$wgVectorStickyHeaderEdit = [
"logged_in" => true,
"logged_out" => false,
];
$wgVectorWebABTestEnrollment = [
"name" => "vector.sticky_header_edit",
"enabled" => true,
"buckets" => [
"unsampled" => [
"samplingRate" => 0
],
"noStickyHeaderControl" => [
"samplingRate" => 0.34
],
"stickyHeaderNoEditButtonTreatment1" => [
"samplingRate" => 0.33
],
"stickyHeaderEditButtonTreatment2" => [
"samplingRate" => 0.33
]
],
];
```
Bug: T312573
Change-Id: I15c360fdf5393f5594602acc33b5b916e904016d
2022-07-07 19:06:14 +00:00
|
|
|
].forEach(
|
|
|
|
( {
|
2022-05-31 22:32:50 +00:00
|
|
|
abConfig,
|
|
|
|
isEnabled,
|
Sticky header AB test bucketing for 2 treatment buckets
For idwiki/viwiki, we wish to run the sticky header edit button AB
test so that treatment1 group sees the sticky header without edit
buttons, treatment2 groups sees the sticky header with edit buttons,
and the control/unsampled groups see no sticky header at all.
This patch overrides the configuration to make the sticky header
w/o edit buttons for treatment1, sticky header w/ edit buttons for
treatment2, and hides sticky header for everyone else. This depends
on a configuration with the treatment groups having "treatment1"
and "treatment2" as substrings in their bucket names.
The full configuration for idwiki/viwiki would be something like
the following:
```
$wgVectorStickyHeader = [
"logged_in" => true,
"logged_out" => false,
];
$wgVectorStickyHeaderEdit = [
"logged_in" => true,
"logged_out" => false,
];
$wgVectorWebABTestEnrollment = [
"name" => "vector.sticky_header_edit",
"enabled" => true,
"buckets" => [
"unsampled" => [
"samplingRate" => 0
],
"noStickyHeaderControl" => [
"samplingRate" => 0.34
],
"stickyHeaderNoEditButtonTreatment1" => [
"samplingRate" => 0.33
],
"stickyHeaderEditButtonTreatment2" => [
"samplingRate" => 0.33
]
],
];
```
Bug: T312573
Change-Id: I15c360fdf5393f5594602acc33b5b916e904016d
2022-07-07 19:06:14 +00:00
|
|
|
isUserInTreatmentBucket,
|
|
|
|
expectedResult
|
|
|
|
} ) => {
|
|
|
|
document.documentElement.classList.add( 'vector-sticky-header-enabled' );
|
|
|
|
const result = test.initStickyHeaderABTests(
|
|
|
|
abConfig,
|
|
|
|
// isStickyHeaderFeatureAllowed
|
|
|
|
isEnabled,
|
|
|
|
( experiment ) => ( {
|
|
|
|
name: experiment.name,
|
|
|
|
isInBucket: () => true,
|
|
|
|
isInSample: () => true,
|
|
|
|
getBucket: () => 'bucket',
|
|
|
|
isInTreatmentBucket: () => {
|
|
|
|
return isUserInTreatmentBucket;
|
|
|
|
}
|
|
|
|
} )
|
|
|
|
);
|
|
|
|
expect( result ).toMatchObject( expectedResult );
|
|
|
|
// Check that there are no side effects
|
|
|
|
expect(
|
|
|
|
document.documentElement.classList.contains( 'vector-sticky-header-enabled' )
|
|
|
|
).toBe( true );
|
|
|
|
} );
|
2022-05-31 22:32:50 +00:00
|
|
|
} );
|
2022-03-17 16:54:26 +00:00
|
|
|
} );
|
2023-02-16 01:20:00 +00:00
|
|
|
|
|
|
|
const sectionObserverFn = () => ( {
|
|
|
|
pause: () => {},
|
|
|
|
resume: () => {},
|
|
|
|
mount: () => {},
|
|
|
|
unmount: () => {},
|
2023-03-03 08:32:02 +00:00
|
|
|
setElements: () => {},
|
|
|
|
calcIntersection: () => {}
|
2023-02-16 01:20:00 +00:00
|
|
|
} );
|
|
|
|
|
|
|
|
describe( 'Table of contents re-rendering', () => {
|
|
|
|
const mockMwHook = () => {
|
|
|
|
/** @type {Object.<string, Function>} */
|
|
|
|
let callback = {};
|
|
|
|
// @ts-ignore
|
|
|
|
jest.spyOn( mw, 'hook' ).mockImplementation( ( name ) => {
|
|
|
|
|
|
|
|
return {
|
|
|
|
add: function ( fn ) {
|
|
|
|
callback[ name ] = fn;
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
fire: ( data ) => {
|
|
|
|
if ( callback[ name ] ) {
|
|
|
|
callback[ name ]( data );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} );
|
|
|
|
};
|
|
|
|
|
|
|
|
afterEach( () => {
|
|
|
|
jest.restoreAllMocks();
|
|
|
|
} );
|
|
|
|
|
|
|
|
it( 'listens to wikipage.tableOfContents hook when mounted', () => {
|
|
|
|
mockMwHook();
|
|
|
|
const spy = jest.spyOn( mw, 'hook' );
|
|
|
|
const tocElement = document.createElement( 'div' );
|
|
|
|
const bodyContent = document.createElement( 'article' );
|
2023-02-28 19:48:31 +00:00
|
|
|
const toc = test.setupTableOfContents( tocElement, bodyContent, sectionObserverFn );
|
2023-02-16 01:20:00 +00:00
|
|
|
expect( toc ).not.toBe( null );
|
|
|
|
expect( spy ).toHaveBeenCalledWith( 'wikipage.tableOfContents' );
|
|
|
|
expect( spy ).not.toHaveBeenCalledWith( 'wikipage.tableOfContents.vector' );
|
|
|
|
} );
|
|
|
|
|
|
|
|
it( 'Firing wikipage.tableOfContents triggers reloadTableOfContents', async () => {
|
|
|
|
mockMwHook();
|
|
|
|
const tocElement = document.createElement( 'div' );
|
|
|
|
const bodyContent = document.createElement( 'article' );
|
2023-02-28 19:48:31 +00:00
|
|
|
const toc = test.setupTableOfContents( tocElement, bodyContent, sectionObserverFn );
|
2023-02-16 01:20:00 +00:00
|
|
|
if ( !toc ) {
|
|
|
|
// something went wrong
|
|
|
|
expect( true ).toBe( false );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const spy = jest.spyOn( toc, 'reloadTableOfContents' ).mockImplementation( () => Promise.resolve() );
|
|
|
|
|
|
|
|
mw.hook( 'wikipage.tableOfContents' ).fire( [
|
|
|
|
// Add new section to see how the re-render performs.
|
|
|
|
{
|
|
|
|
toclevel: 1,
|
|
|
|
number: '4',
|
|
|
|
line: 'bat',
|
|
|
|
anchor: 'bat',
|
|
|
|
'is-top-level-section': true,
|
|
|
|
'is-parent-section': false,
|
|
|
|
'array-sections': null
|
|
|
|
}
|
|
|
|
] );
|
|
|
|
|
|
|
|
expect( spy ).toHaveBeenCalled();
|
|
|
|
} );
|
|
|
|
} );
|