Merge pull request #596 from ueokande/qa-0.23

QA 0.23
jh-changes
Shin'ya Ueoka 5 years ago committed by GitHub
commit 68673957ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      QA.md
  2. 34
      e2e/follow_properties.test.js
  3. 10405
      package-lock.json
  4. 12
      package.json
  5. 5
      src/background/usecases/CompletionsUseCase.ts
  6. 10
      src/content/usecases/FollowSlaveUseCase.ts
  7. 7
      src/settings/components/form/SearchForm.tsx
  8. 2
      src/settings/components/index.tsx
  9. 12
      src/settings/keymaps.ts
  10. 28
      src/shared/Settings.ts
  11. 4
      test/shared/Settings.test.ts

@ -20,10 +20,8 @@ The behaviors of the console are tested in [Console section](#consoles).
### Properties
- [ ] Configure custom hint character by `:set hintchars=012345678`
- [ ] Smooth scroll by `:set smoothscroll`
- [ ] Non-smooth scroll by `:set nosmoothscroll`
- [ ] Configure smooth scroll by settings `"smoothscroll": true`, `"smoothscroll": false`
- [ ] Toggle smooth scroll by `:set smoothscroll` and `:set nosmoothscroll`
- [ ] Configure smooth scroll by settings `"smoothscroll": true` and `"smoothscroll": false`
### Settings
@ -45,7 +43,6 @@ The behaviors of the console are tested in [Console section](#consoles).
##### Updating
- [ ] changes are updated on textarea blure when no errors
- [ ] changes are not updated on textarea blure when errors occurs
- [ ] keymap settings are applied to open tabs without reload
- [ ] search settings are applied to open tabs without reload

@ -3,6 +3,7 @@ const lanthan = require('lanthan');
const path = require('path');
const assert = require('assert');
const eventually = require('./eventually');
const Console = require('./lib/Console');
const Key = lanthan.Key;
@ -114,7 +115,6 @@ describe('follow properties test', () => {
assert.equal(await hints[2].getStyle('display'), 'block');
assert.equal(await hints[3].getStyle('display'), 'block');
assert.equal(await hints[4].getStyle('display'), 'none');
});
});
@ -147,4 +147,36 @@ describe('follow properties test', () => {
assert.equal(tabs[1].active, false);
});
});
it('should show hints with hintchars by settings', async () => {
let c = new Console(session);
await body.sendKeys(':');
await session.switchToFrame(0);
await c.sendKeys('set hintchars=abc', Key.Enter);
await session.switchToParentFrame();
await body.sendKeys('f');
await eventually(async() => {
let hints = await session.findElementsByCSS('.vimvixen-hint');
assert.equal(hints.length, 5);
assert.equal(await hints[0].getText(), 'A');
assert.equal(await hints[1].getText(), 'B');
assert.equal(await hints[2].getText(), 'C');
assert.equal(await hints[3].getText(), 'AA');
assert.equal(await hints[4].getText(), 'AB');
});
await body.sendKeys('a');
await eventually(async() => {
let hints = await session.findElementsByCSS('.vimvixen-hint');
assert.equal(await hints[0].getStyle('display'), 'block');
assert.equal(await hints[1].getStyle('display'), 'none');
assert.equal(await hints[2].getStyle('display'), 'none');
assert.equal(await hints[3].getStyle('display'), 'block');
assert.equal(await hints[4].getStyle('display'), 'block');
});
});
});

10405
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -24,16 +24,16 @@
"@types/chai": "^4.1.7",
"@types/mocha": "^5.2.6",
"@types/prop-types": "^15.7.1",
"@types/react": "^16.8.15",
"@types/react": "^16.8.18",
"@types/react-dom": "^16.8.4",
"@types/react-redux": "^7.0.8",
"@types/react-redux": "^7.0.9",
"@types/redux-promise": "^0.5.28",
"@types/sinon": "^7.0.11",
"@typescript-eslint/eslint-plugin": "^1.9.0",
"chai": "^4.2.0",
"css-loader": "^2.1.1",
"eslint": "^5.16.0",
"eslint-plugin-react": "^7.12.4",
"eslint-plugin-react": "^7.13.0",
"html-webpack-plugin": "^3.2.0",
"jszip": "^3.2.1",
"karma": "^4.1.0",
@ -62,8 +62,8 @@
"tsyringe": "^3.2.0",
"typescript": "^3.4.5",
"web-ext-types": "^3.1.0",
"webextensions-api-fake": "^0.7.4",
"webpack": "^4.30.0",
"webpack-cli": "^3.3.1"
"webextensions-api-fake": "^0.8.0",
"webpack": "^4.32.2",
"webpack-cli": "^3.3.2"
}
}

@ -38,6 +38,9 @@ export default class CompletionsUseCase {
}
async queryOpen(name: string, keywords: string): Promise<CompletionGroup[]> {
// TODO This logic contains view entities. They should be defined on
// content script
let settings = await this.settingRepository.get();
let groups: CompletionGroup[] = [];
@ -195,7 +198,7 @@ export default class CompletionsUseCase {
.map(pages => filters.filterByPathname(pages, COMPLETION_ITEM_LIMIT))
.map(pages => filters.filterByOrigin(pages, COMPLETION_ITEM_LIMIT))[0]
.sort((x: HistoryItem, y: HistoryItem): number => {
return Number(x.visitCount) - Number(y.visitCount);
return Number(y.visitCount) - Number(x.visitCount);
})
.slice(0, COMPLETION_ITEM_LIMIT);
return histories.map(page => ({

@ -63,16 +63,16 @@ export default class FollowSlaveUseCase {
if (hint instanceof LinkHint) {
let url = hint.getLink();
// ignore taget='_blank'
if (!newTab && hint.getLinkTarget() === '_blank') {
hint.click();
return;
let openNewTab = newTab;
// Open link by background script in order to prevent a popup block
if (hint.getLinkTarget() === '_blank') {
openNewTab = true;
}
// eslint-disable-next-line no-script-url
if (!url || url === '#' || url.toLowerCase().startsWith('javascript:')) {
return;
}
await this.tabsClient.openUrl(url, newTab, background);
await this.tabsClient.openUrl(url, openNewTab, background);
} else if (hint instanceof InputHint) {
hint.activate();
}

@ -54,6 +54,7 @@ class SearchForm extends React.Component<Props> {
</div>;
}
// eslint-disable-next-line max-statements
bindValue(e: any) {
let value = this.props.value.toJSON();
let name = e.target.name;
@ -72,8 +73,12 @@ class SearchForm extends React.Component<Props> {
next.default = value.engines[index][0];
} else if (name === 'add') {
next.engines.push(['', '']);
} else if (name === 'delete') {
} else if (name === 'delete' && value.engines.length > 1) {
next.engines.splice(index, 1);
if (value.engines[index][0] === value.default) {
let nextIndex = Math.min(index, next.engines.length - 1);
next.default = next.engines[nextIndex][0];
}
}
this.props.onChange(FormSearch.valueOf(next));

@ -175,6 +175,7 @@ class SettingsComponent extends React.Component<Props> {
if (from === 'form' && value === 'json') {
this.props.dispatch(settingActions.switchToJson(
this.props.form as FormSettings));
this.save();
} else if (from === 'json' && value === 'form') {
let b = window.confirm(DO_YOU_WANT_TO_CONTINUE);
if (!b) {
@ -183,6 +184,7 @@ class SettingsComponent extends React.Component<Props> {
}
this.props.dispatch(
settingActions.switchToForm(this.props.json as JSONSettings));
this.save();
}
}

@ -1,3 +1,5 @@
/* eslint-disable max-len */
const fields = [
[
['scroll.vertically?{"count":1}', 'Scroll down'],
@ -19,8 +21,8 @@ const fields = [
['tabs.close', 'Close a tab'],
['tabs.close.right', 'Close tabs to the right'],
['tabs.reopen', 'Reopen closed tab'],
['tabs.next?{"count":1}', 'Select next Tab'],
['tabs.prev?{"count":1}', 'Select prev Tab'],
['tabs.next', 'Select next Tab'],
['tabs.prev', 'Select prev Tab'],
['tabs.first', 'Select first tab'],
['tabs.last', 'Select last tab'],
['tabs.reload?{"cache":false}', 'Reload current tab'],
@ -28,8 +30,8 @@ const fields = [
['tabs.pin.toggle', 'Toggle pinned state'],
['tabs.duplicate', 'Duplicate a tab'],
], [
['follow.start?{"newTab":false}', 'Follow a link'],
['follow.start?{"newTab":true}', 'Follow a link in new tab'],
['follow.start?{"newTab":false,"background":false}', 'Follow a link'],
['follow.start?{"newTab":true,"background":false}', 'Follow a link in new tab'],
['navigate.history.prev', 'Go back in histories'],
['navigate.history.next', 'Go forward in histories'],
['navigate.link.next', 'Open next link'],
@ -37,7 +39,7 @@ const fields = [
['navigate.parent', 'Go to parent directory'],
['navigate.root', 'Go to root directory'],
['page.source', 'Open page source'],
['page.home', 'Open start page to current tab'],
['page.home?{"newTab":false}', 'Open start page to current tab'],
['page.home?{"newTab":true}', 'Open start page in new tab'],
['focus.input', 'Focus input'],
], [

@ -101,17 +101,23 @@ export const blacklistValueOf = (o: any): string[] => {
export const valueOf = (o: any): Settings => {
let settings = { ...DefaultSetting };
if (Object.prototype.hasOwnProperty.call(o, 'keymaps')) {
settings.keymaps = keymapsValueOf(o.keymaps);
}
if (Object.prototype.hasOwnProperty.call(o, 'search')) {
settings.search = searchValueOf(o.search);
}
if (Object.prototype.hasOwnProperty.call(o, 'properties')) {
settings.properties = propertiesValueOf(o.properties);
}
if (Object.prototype.hasOwnProperty.call(o, 'blacklist')) {
settings.blacklist = blacklistValueOf(o.blacklist);
for (let key of Object.keys(o)) {
switch (key) {
case 'keymaps':
settings.keymaps = keymapsValueOf(o.keymaps);
break;
case 'search':
settings.search = searchValueOf(o.search);
break;
case 'properties':
settings.properties = propertiesValueOf(o.properties);
break;
case 'blacklist':
settings.blacklist = blacklistValueOf(o.blacklist);
break;
default:
throw new TypeError('unknown setting: ' + key);
}
}
return settings;
};

@ -186,5 +186,9 @@ describe('Settings', () => {
expect(value.search.engines).to.be.an('object');
expect(value.blacklist).to.be.empty;
});
it('throws a TypeError with an unknown field', () => {
expect(() => settings.valueOf({ name: 'alice' })).to.throw(TypeError)
});
});
});