feat(aio): include more API results in search
By adding a more relaxed search on the title of docs, we are more likely to catch API docs. The additional search terms match anything with a word in the title that starts with the characters of the first term in the search. E.g. if the search is "ngCont guide" then search for "ngCont guide titleWords:ngCont*"
This commit is contained in:
parent
917d0870e8
commit
4a0466e574
|
@ -92,4 +92,10 @@ describe('site App', function() {
|
||||||
// Todo: add test to confirm tracking URL when navigate.
|
// Todo: add test to confirm tracking URL when navigate.
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('search', () => {
|
||||||
|
it('should find pages when searching by a partial word in the title', () => {
|
||||||
|
page.enterSearch('ngCont');
|
||||||
|
expect(page.getSearchResults().map(link => link.getText())).toContain('NgControl');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { browser, element, by, promise, ElementFinder } from 'protractor';
|
import { browser, element, by, promise, ElementFinder, ExpectedConditions } from 'protractor';
|
||||||
|
|
||||||
const githubRegex = /https:\/\/github.com\/angular\/angular\//;
|
const githubRegex = /https:\/\/github.com\/angular\/angular\//;
|
||||||
|
|
||||||
|
@ -50,6 +50,16 @@ export class SitePage {
|
||||||
return browser.executeScript('window.scrollTo(0, document.body.scrollHeight)');
|
return browser.executeScript('window.scrollTo(0, document.body.scrollHeight)');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enterSearch(query: string) {
|
||||||
|
element(by.css('.search-container input[type=search]')).sendKeys(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
getSearchResults() {
|
||||||
|
const results = element.all(by.css('.search-results li'));
|
||||||
|
browser.wait(ExpectedConditions.presenceOf(results.first()), 8000);
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replace the ambient Google Analytics tracker with homebrew spy
|
* Replace the ambient Google Analytics tracker with homebrew spy
|
||||||
* don't send commands to GA during e2e testing!
|
* don't send commands to GA during e2e testing!
|
||||||
|
|
|
@ -9,7 +9,18 @@ var SEARCH_TERMS_URL = '/generated/docs/app/search-data.json';
|
||||||
importScripts('/assets/js/lunr.min.js');
|
importScripts('/assets/js/lunr.min.js');
|
||||||
|
|
||||||
var index;
|
var index;
|
||||||
var pages = {};
|
var pages /* : SearchInfo */ = {};
|
||||||
|
|
||||||
|
// interface SearchInfo {
|
||||||
|
// [key: string]: PageInfo;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// interface PageInfo {
|
||||||
|
// path: string;
|
||||||
|
// type: string,
|
||||||
|
// titleWords: string;
|
||||||
|
// keyWords: string;
|
||||||
|
// }
|
||||||
|
|
||||||
self.onmessage = handleMessage;
|
self.onmessage = handleMessage;
|
||||||
|
|
||||||
|
@ -49,15 +60,7 @@ function handleMessage(message) {
|
||||||
// Use XHR to make a request to the server
|
// Use XHR to make a request to the server
|
||||||
function makeRequest(url, callback) {
|
function makeRequest(url, callback) {
|
||||||
|
|
||||||
// The JSON file that is loaded should be an array of SearchTerms:
|
// The JSON file that is loaded should be an array of PageInfo:
|
||||||
//
|
|
||||||
// export interface SearchTerms {
|
|
||||||
// path: string;
|
|
||||||
// type: string,
|
|
||||||
// titleWords: string;
|
|
||||||
// keyWords: string;
|
|
||||||
// }
|
|
||||||
|
|
||||||
var searchDataRequest = new XMLHttpRequest();
|
var searchDataRequest = new XMLHttpRequest();
|
||||||
searchDataRequest.onload = function() {
|
searchDataRequest.onload = function() {
|
||||||
callback(JSON.parse(this.responseText));
|
callback(JSON.parse(this.responseText));
|
||||||
|
@ -68,11 +71,11 @@ function makeRequest(url, callback) {
|
||||||
|
|
||||||
|
|
||||||
// Create the search index from the searchInfo which contains the information about each page to be indexed
|
// Create the search index from the searchInfo which contains the information about each page to be indexed
|
||||||
function loadIndex(searchInfo) {
|
function loadIndex(searchInfo /*: SearchInfo */) {
|
||||||
return function(index) {
|
return function(index) {
|
||||||
// Store the pages data to be used in mapping query results back to pages
|
// Store the pages data to be used in mapping query results back to pages
|
||||||
// Add search terms from each page to the search index
|
// Add search terms from each page to the search index
|
||||||
searchInfo.forEach(function(page) {
|
searchInfo.forEach(function(page /*: PageInfo */) {
|
||||||
index.add(page);
|
index.add(page);
|
||||||
pages[page.path] = page;
|
pages[page.path] = page;
|
||||||
});
|
});
|
||||||
|
@ -81,7 +84,19 @@ function loadIndex(searchInfo) {
|
||||||
|
|
||||||
// Query the index and return the processed results
|
// Query the index and return the processed results
|
||||||
function queryIndex(query) {
|
function queryIndex(query) {
|
||||||
var results = index.search(query);
|
try {
|
||||||
// Only return the array of paths to pages
|
if (query.length) {
|
||||||
return results.map(function(hit) { return pages[hit.ref]; });
|
// Add a relaxed search in the title for the first word in the query
|
||||||
|
// E.g. if the search is "ngCont guide" then we search for "ngCont guide titleWords:ngCont*"
|
||||||
|
var titleQuery = 'titleWords:' + query.split(' ', 1)[0] + '*';
|
||||||
|
var results = index.search(query + ' ' + titleQuery);
|
||||||
|
// Map the hits into info about each page to be returned as results
|
||||||
|
return results.map(function(hit) { return pages[hit.ref]; });
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
// If the search query cannot be parsed the index throws an error
|
||||||
|
// Log it and recover
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue